Suppress "redundant parens" warning for "A (::B())".
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 21 Dec 2017 22:26:47 +0000 (22:26 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 21 Dec 2017 22:26:47 +0000 (22:26 +0000)
This is a slightly odd construct (it's more common to see "A (::B)()") but can
happen in friend declarations, and the parens are not redundant as they prevent
the :: binding to the left.

llvm-svn: 321318

clang/lib/Sema/SemaType.cpp
clang/test/Parser/cxx-decl.cpp
clang/test/SemaCXX/decl-expr-ambiguity.cpp

index b45d31c..63a4963 100644 (file)
@@ -3165,7 +3165,12 @@ static void warnAboutRedundantParens(Sema &S, Declarator &D, QualType T) {
       // In a new-type-id, function chunks require parentheses.
       if (D.getContext() == Declarator::CXXNewContext)
         return;
-      LLVM_FALLTHROUGH;
+      // FIXME: "A(f())" deserves a vexing-parse warning, not just a
+      // redundant-parens warning, but we don't know whether the function
+      // chunk was syntactically valid as an expression here.
+      CouldBeTemporaryObject = false;
+      continue;
+
     case DeclaratorChunk::BlockPointer:
     case DeclaratorChunk::MemberPointer:
     case DeclaratorChunk::Pipe:
index 711a874..58ad080 100644 (file)
@@ -282,6 +282,22 @@ namespace NNS {
   }
 }
 
+inline namespace ParensAroundFriend { // expected-error 0-1{{C++11}}
+  struct A {};
+  struct B {
+    static A C();
+  };
+  namespace X {
+    struct B {};
+    struct D {
+      // No warning here: while this could be written as
+      //   friend (::B::C)();
+      // we do need parentheses *somewhere* here.
+      friend A (::B::C());
+    };
+  }
+}
+
 // PR8380
 extern ""      // expected-error {{unknown linkage language}}
 test6a { ;// expected-error {{C++ requires a type specifier for all declarations}}
index 1e31d70..b77e226 100644 (file)
@@ -125,3 +125,20 @@ void fizbin() {
   baz b3; // expected-error {{must use 'class' tag to refer to type 'baz' in this scope}}
 }
 }
+
+namespace TemporaryFromFunctionCall {
+  struct A {
+    A(int);
+  };
+  int f();
+  int g(int);
+  namespace N {
+    void x() {
+      // FIXME: For the first and second of these (but not the third), we
+      // should produce a vexing-parse warning.
+      A(f());
+      A(g(int()));
+      A(g(int));
+    }
+  }
+}