PR10828: Produce a warning when a no-arguments function is declared in block
scope, when no other indication is provided that the user intended to declare a
function rather than a variable.

Remove some false positives from the existing 'parentheses disambiguated as a
function' warning by suppressing it when the declaration is marked as 'typedef'
or 'extern'.

Add a new warning group -Wvexing-parse containing both of these warnings.

The new warning is enabled by default; despite a number of false positives (and
one bug) in clang's test-suite, I have only found genuine bugs with it when
running it over a significant quantity of real C++ code.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147599 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CXX/basic/basic.link/p9.cpp b/test/CXX/basic/basic.link/p9.cpp
index bd16b02..c895253 100644
--- a/test/CXX/basic/basic.link/p9.cpp
+++ b/test/CXX/basic/basic.link/p9.cpp
@@ -6,6 +6,5 @@
 // First bullet: two names with external linkage that refer to
 // different kinds of entities.
 void f() {
-  int N(); // expected-error{{redefinition}}
+  int N(); // expected-error{{redefinition}} expected-warning{{interpreted as a function declaration}}
 }
-
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp
index 63b3022..b1dcf4d 100644
--- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p11.cpp
@@ -25,13 +25,13 @@
 namespace test2 {
   namespace ns { void foo(); } // expected-note 2 {{target of using declaration}}
   void test0() {
-    int foo(); // expected-note {{conflicting declaration}}
+    int foo(); // expected-note {{conflicting declaration}} expected-warning{{function declaration}}
     using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
   }
 
   void test1() {
     using ns::foo; //expected-note {{using declaration}}
-    int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+    int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}} expected-warning{{function declaration}}
   }
 }
 
@@ -39,7 +39,7 @@
   namespace ns { void foo(); } // expected-note 2 {{target of using declaration}}
   class Test0 {
     void test() {
-      int foo(); // expected-note {{conflicting declaration}}
+      int foo(); // expected-note {{conflicting declaration}} expected-warning{{function declaration}}
       using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
     }
   };
@@ -47,7 +47,7 @@
   class Test1 {
     void test() {
       using ns::foo; //expected-note {{using declaration}}
-      int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+      int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}} expected-warning{{function declaration}}
     }
   };
 }
@@ -56,7 +56,7 @@
   namespace ns { void foo(); } // expected-note 2 {{target of using declaration}}
   template <typename> class Test0 {
     void test() {
-      int foo(); // expected-note {{conflicting declaration}}
+      int foo(); // expected-note {{conflicting declaration}} expected-warning{{function declaration}}
       using ns::foo; // expected-error {{target of using declaration conflicts with declaration already in scope}}
     }
   };
@@ -64,7 +64,7 @@
   template <typename> class Test1 {
     void test() {
       using ns::foo; //expected-note {{using declaration}}
-      int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}}
+      int foo(); // expected-error {{declaration conflicts with target of using declaration already in scope}} expected-warning{{function declaration}}
     }
   };
 }
@@ -91,4 +91,3 @@
   template class Test0<int>;
   template class Test1<int>; // expected-note {{in instantiation of member function}}
 }
-
diff --git a/test/Misc/warning-flags.c b/test/Misc/warning-flags.c
index 5e05e0b..42c09cb 100644
--- a/test/Misc/warning-flags.c
+++ b/test/Misc/warning-flags.c
@@ -17,7 +17,7 @@
 
 The list of warnings below should NEVER grow.  It should gradually shrink to 0.
 
-CHECK: Warnings without flags (268):
+CHECK: Warnings without flags (267):
 CHECK-NEXT:   ext_anon_param_requires_type_specifier
 CHECK-NEXT:   ext_anonymous_struct_union_qualified
 CHECK-NEXT:   ext_array_init_copy
@@ -211,7 +211,6 @@
 CHECK-NEXT:   warn_odr_tag_type_inconsistent
 CHECK-NEXT:   warn_on_superclass_use
 CHECK-NEXT:   warn_param_default_argument_redefinition
-CHECK-NEXT:   warn_parens_disambiguated_as_function_decl
 CHECK-NEXT:   warn_partial_specs_not_deducible
 CHECK-NEXT:   warn_pointer_attribute_wrong_type
 CHECK-NEXT:   warn_pp_convert_lhs_to_positive
diff --git a/test/SemaCXX/conditional-expr.cpp b/test/SemaCXX/conditional-expr.cpp
index 5648d02..3cfddb3 100644
--- a/test/SemaCXX/conditional-expr.cpp
+++ b/test/SemaCXX/conditional-expr.cpp
@@ -96,8 +96,8 @@
   (void)(i1 ? BadDerived() : BadBase());
 
   // b2.1 (hierarchy stuff)
-  const Base constret();
-  const Derived constder();
+  const Base constret(); // expected-warning {{interpreted as a function declaration}}
+  const Derived constder(); // expected-warning {{interpreted as a function declaration}}
   // should use const overload
   A a1((i1 ? constret() : Base()).trick());
   A a2((i1 ? Base() : constret()).trick());
diff --git a/test/SemaCXX/decl-expr-ambiguity.cpp b/test/SemaCXX/decl-expr-ambiguity.cpp
index 1ddff80..555e89c 100644
--- a/test/SemaCXX/decl-expr-ambiguity.cpp
+++ b/test/SemaCXX/decl-expr-ambiguity.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -pedantic-errors %s 
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic-errors %s
 
 void f() {
   int a;
@@ -24,10 +24,15 @@
   // Declarations.
   int fd(T(a)); // expected-warning {{parentheses were disambiguated as a function declarator}}
   T(*d)(int(p)); // expected-warning {{parentheses were disambiguated as a function declarator}} expected-note {{previous definition is here}}
+  typedef T(*td)(int(p));
+  extern T(*tp)(int(p));
+  T d3(); // expected-warning {{empty parentheses interpreted as a function declaration}}
+  typedef T d3t();
+  extern T f3();
   T(d)[5]; // expected-error {{redefinition of 'd'}}
   typeof(int[])(f) = { 1, 2 }; // expected-error {{extension used}}
   void(b)(int);
-  int(d2) __attribute__(()); 
+  int(d2) __attribute__(());
   if (int(a)=1) {}
   int(d3(int()));
 }
diff --git a/test/SemaTemplate/class-template-ctor-initializer.cpp b/test/SemaTemplate/class-template-ctor-initializer.cpp
index 81a5e2b..44bb4bd 100644
--- a/test/SemaTemplate/class-template-ctor-initializer.cpp
+++ b/test/SemaTemplate/class-template-ctor-initializer.cpp
@@ -49,7 +49,7 @@
   int
   main (void)
   {
-    Final final();
+    Final final;
     return 0;
   }
 }