diff options
| author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2008-10-15 23:21:32 +0000 | 
|---|---|---|
| committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2008-10-15 23:21:32 +0000 | 
| commit | 84a4df8c92aea8da3002a28923c51c0eccc4ddd6 (patch) | |
| tree | edc7b8be279ae6cdfef88de2a470a4f52b749bbf /clang/lib | |
| parent | bc0278400c6e067212ef1224e4e9bb25fbdbf594 (diff) | |
| download | bcm5719-llvm-84a4df8c92aea8da3002a28923c51c0eccc4ddd6.tar.gz bcm5719-llvm-84a4df8c92aea8da3002a28923c51c0eccc4ddd6.zip  | |
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
llvm-svn: 57609
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 5 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseTentative.cpp | 14 | 
2 files changed, 14 insertions, 5 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index c541a1336f4..142347687e2 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -1226,11 +1226,14 @@ void Parser::ParseDirectDeclarator(Declarator &D) {    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)) { diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index 5dbc327b713..1666e39ee1a 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -453,7 +453,7 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,        // 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 @@ Parser::TPResult Parser::TryParseDeclarationSpecifier() {  /// '(' 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 @@ bool Parser::isCXXFunctionDeclarator() {    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();  }  | 

