[cfe-commits] r57609 - in /cfe/trunk: include/clang/Basic/DiagnosticKinds.def include/clang/Parse/Parser.h lib/Parse/ParseDecl.cpp lib/Parse/ParseTentative.cpp test/SemaCXX/decl-expr-ambiguity.cpp
Argiris Kirtzidis
akyrtzi at gmail.com
Wed Oct 15 16:21:33 PDT 2008
Author: akirtzidis
Date: Wed Oct 15 18:21:32 2008
New Revision: 57609
URL: http://llvm.org/viewvc/llvm-project?rev=57609&view=rev
Log:
Issue a warning when there's an ambiguous function declarator (that could be a direct initializer for a variable defition).
Idea originated from here: http://thread.gmane.org/gmane.comp.gcc.devel/101524
Modified:
cfe/trunk/include/clang/Basic/DiagnosticKinds.def
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseTentative.cpp
cfe/trunk/test/SemaCXX/decl-expr-ambiguity.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=57609&r1=57608&r2=57609&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Oct 15 18:21:32 2008
@@ -557,6 +557,8 @@
"expected '=' after declarator")
DIAG(warn_statement_disambiguation, WARNING,
"statement was disambiguated as %0")
+DIAG(warn_parens_disambiguated_as_function_decl, WARNING,
+ "parentheses were disambiguated as a function declarator")
// Language specific pragmas
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=57609&r1=57608&r2=57609&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Wed Oct 15 18:21:32 2008
@@ -615,10 +615,11 @@
/// isCXXFunctionDeclarator - Disambiguates between a function declarator or
/// a constructor-style initializer, when parsing declaration statements.
/// Returns true for function declarator and false for constructor-style
- /// initializer.
+ /// initializer. If 'diagIfAmbiguous' is true a warning will be emitted to
+ /// indicate that the parens were disambiguated as function declarator.
/// If during the disambiguation process a parsing error is encountered,
/// the function returns true to let the declaration parsing code handle it.
- bool isCXXFunctionDeclarator();
+ bool isCXXFunctionDeclarator(bool diagIfAmbiguous);
/// isCXXConditionDeclaration - Disambiguates between a declaration or an
/// expression for a condition of a if/switch/while/for statement.
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=57609&r1=57608&r2=57609&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed Oct 15 18:21:32 2008
@@ -1226,11 +1226,14 @@
while (1) {
if (Tok.is(tok::l_paren)) {
+ // When not in file scope, warn for ambiguous function declarators, just
+ // in case the author intended it as a variable definition.
+ bool diagIfAmbiguous = D.getContext() != Declarator::FileContext;
// The paren may be part of a C++ direct initializer, eg. "int x(1);".
// In such a case, check if we actually have a function declarator; if it
// is not, the declarator has been fully parsed.
if (getLang().CPlusPlus && D.mayBeFollowedByCXXDirectInit() &&
- !isCXXFunctionDeclarator())
+ !isCXXFunctionDeclarator(diagIfAmbiguous))
break;
ParseFunctionDeclarator(ConsumeParen(), D);
} else if (Tok.is(tok::l_square)) {
Modified: cfe/trunk/lib/Parse/ParseTentative.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTentative.cpp?rev=57609&r1=57608&r2=57609&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTentative.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTentative.cpp Wed Oct 15 18:21:32 2008
@@ -453,7 +453,7 @@
// initializer that follows the declarator. Note that ctor-style
// initializers are not possible in contexts where abstract declarators
// are allowed.
- if (!mayBeAbstract && !isCXXFunctionDeclarator())
+ if (!mayBeAbstract && !isCXXFunctionDeclarator(false/*diagIfAmbiguous*/))
break;
// direct-declarator '(' parameter-declaration-clause ')'
@@ -722,7 +722,7 @@
/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
/// exception-specification[opt]
///
-bool Parser::isCXXFunctionDeclarator() {
+bool Parser::isCXXFunctionDeclarator(bool diagIfAmbiguous) {
// C++ 8.2p1:
// The ambiguity arising from the similarity between a function-style cast and
@@ -740,15 +740,21 @@
if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren))
TPR = TPResult::False();
+ SourceLocation TPLoc = Tok.getLocation();
PA.Revert();
// In case of an error, let the declaration parsing code handle it.
if (TPR == TPResult::Error())
return true;
- // Function declarator has precedence over constructor-style initializer.
- if (TPR == TPResult::Ambiguous())
+ if (TPR == TPResult::Ambiguous()) {
+ // Function declarator has precedence over constructor-style initializer.
+ // Emit a warning just in case the author intended a variable definition.
+ if (diagIfAmbiguous)
+ Diag(Tok.getLocation(), diag::warn_parens_disambiguated_as_function_decl,
+ SourceRange(Tok.getLocation(), TPLoc));
return true;
+ }
return TPR == TPResult::True();
}
Modified: cfe/trunk/test/SemaCXX/decl-expr-ambiguity.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/decl-expr-ambiguity.cpp?rev=57609&r1=57608&r2=57609&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/decl-expr-ambiguity.cpp (original)
+++ cfe/trunk/test/SemaCXX/decl-expr-ambiguity.cpp Wed Oct 15 18:21:32 2008
@@ -22,7 +22,8 @@
(int())1; // expected-error {{used type 'int ()' where arithmetic or pointer type is required}}
// Declarations.
- T(*d)(int(p)); // expected-warning {{statement was disambiguated as declaration}} expected-error {{previous definition is here}}
+ 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-warning {{statement was disambiguated as declaration}} expected-error {{previous definition is here}}
T(d)[5]; // expected-warning {{statement was disambiguated as declaration}} expected-error {{redefinition of 'd'}}
typeof(int[])(f) = { 1, 2 }; // expected-warning {{statement was disambiguated as declaration}}
void(b)(int);
More information about the cfe-commits
mailing list