r321304 - Don't produce redundant parentheses warning for "A (::B); " and the like.
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Thu Dec 21 12:50:39 PST 2017
Author: rsmith
Date: Thu Dec 21 12:50:39 2017
New Revision: 321304
URL: http://llvm.org/viewvc/llvm-project?rev=321304&view=rev
Log:
Don't produce redundant parentheses warning for "A (::B);" and the like.
The parentheses here are not redundant as they affect the binding of the
'::' token.
Modified:
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/test/Parser/cxx-decl.cpp
Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=321304&r1=321303&r2=321304&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Thu Dec 21 12:50:39 2017
@@ -3137,10 +3137,14 @@ static void warnAboutRedundantParens(Sem
(T->isRecordType() || T->isDependentType()) &&
D.getDeclSpec().getTypeQualifiers() == 0 && D.isFirstDeclarator();
+ bool StartsWithDeclaratorId = true;
for (auto &C : D.type_objects()) {
switch (C.Kind) {
- case DeclaratorChunk::Pointer:
case DeclaratorChunk::Paren:
+ if (&C == &Paren)
+ continue;
+ case DeclaratorChunk::Pointer:
+ StartsWithDeclaratorId = false;
continue;
case DeclaratorChunk::Array:
@@ -3154,6 +3158,7 @@ static void warnAboutRedundantParens(Sem
// We assume that something like 'T (&x) = y;' is highly likely to not
// be intended to be a temporary object.
CouldBeTemporaryObject = false;
+ StartsWithDeclaratorId = false;
continue;
case DeclaratorChunk::Function:
@@ -3166,6 +3171,7 @@ static void warnAboutRedundantParens(Sem
case DeclaratorChunk::Pipe:
// These cannot appear in expressions.
CouldBeTemporaryObject = false;
+ StartsWithDeclaratorId = false;
continue;
}
}
@@ -3186,6 +3192,18 @@ static void warnAboutRedundantParens(Sem
SourceRange ParenRange(Paren.Loc, Paren.EndLoc);
if (!CouldBeTemporaryObject) {
+ // If we have A (::B), the parentheses affect the meaning of the program.
+ // Suppress the warning in that case. Don't bother looking at the DeclSpec
+ // here: even (e.g.) "int ::x" is visually ambiguous even though it's
+ // formally unambiguous.
+ if (StartsWithDeclaratorId && D.getCXXScopeSpec().isValid()) {
+ for (NestedNameSpecifier *NNS = D.getCXXScopeSpec().getScopeRep(); NNS;
+ NNS = NNS->getPrefix()) {
+ if (NNS->getKind() == NestedNameSpecifier::Global)
+ return;
+ }
+ }
+
S.Diag(Paren.Loc, diag::warn_redundant_parens_around_declarator)
<< ParenRange << FixItHint::CreateRemoval(Paren.Loc)
<< FixItHint::CreateRemoval(Paren.EndLoc);
Modified: cfe/trunk/test/Parser/cxx-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-decl.cpp?rev=321304&r1=321303&r2=321304&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-decl.cpp (original)
+++ cfe/trunk/test/Parser/cxx-decl.cpp Thu Dec 21 12:50:39 2017
@@ -1,6 +1,6 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -triple i386-linux -pedantic-errors -fcxx-exceptions -fexceptions %s
-// RUN: %clang_cc1 -verify -fsyntax-only -triple i386-linux -pedantic-errors -fcxx-exceptions -fexceptions -std=c++98 %s
-// RUN: %clang_cc1 -verify -fsyntax-only -triple i386-linux -pedantic-errors -fcxx-exceptions -fexceptions -std=c++11 %s
+// RUN: %clang_cc1 -verify -fsyntax-only -triple i386-linux -Wredundant-parens -pedantic-errors -fcxx-exceptions -fexceptions %s
+// RUN: %clang_cc1 -verify -fsyntax-only -triple i386-linux -Wredundant-parens -pedantic-errors -fcxx-exceptions -fexceptions -std=c++98 %s
+// RUN: %clang_cc1 -verify -fsyntax-only -triple i386-linux -Wredundant-parens -pedantic-errors -fcxx-exceptions -fexceptions -std=c++11 %s
const char const *x10; // expected-error {{duplicate 'const' declaration specifier}}
@@ -83,7 +83,7 @@ namespace Commas {
int global1,
__attribute__(()) global2,
- (global5),
+ (global5), // expected-warning {{redundant parentheses surrounding declarator}}
*global6,
&global7 = global1,
&&global8 = static_cast<int&&>(global1),
@@ -263,6 +263,25 @@ namespace DuplicateFriend {
};
}
+namespace NNS {
+ struct A {};
+ namespace B { extern A C1, C2, *C3, C4[], C5; }
+ // Do not produce a redundant parentheses warning here; removing these parens
+ // changes the meaning of the program.
+ A (::NNS::B::C1);
+ A (NNS::B::C2); // expected-warning {{redundant parentheses surrounding declarator}}
+ A (*::NNS::B::C3); // expected-warning {{redundant parentheses surrounding declarator}}
+ A (::NNS::B::C4[2]);
+ // Removing one of these sets of parentheses would be reasonable.
+ A ((::NNS::B::C5)); // expected-warning {{redundant parentheses surrounding declarator}}
+
+ void f() {
+ // FIXME: A vexing-parse warning here would be useful.
+ A(::NNS::B::C1); // expected-error {{definition or redeclaration}}
+ A(NNS::B::C1); // expected-warning {{redundant paren}} expected-error {{definition or redeclaration}}
+ }
+}
+
// PR8380
extern "" // expected-error {{unknown linkage language}}
test6a { ;// expected-error {{C++ requires a type specifier for all declarations}}
More information about the cfe-commits
mailing list