From: Serge Pavlov Date: Tue, 8 Oct 2013 16:56:30 +0000 (+0000) Subject: Add fixits suggesting parenthesis around type name in expressions like sizeof. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2a0a49612ec8866fe2e75b1e0aab04326861b5f2;p=clang Add fixits suggesting parenthesis around type name in expressions like sizeof. This fixes PR16992 - Fixit missing when "sizeof type" found. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@192200 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 8f5ce698ce..71463d53ef 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -310,6 +310,8 @@ def err_unspecified_vla_size_with_static : Error< def warn_deprecated_register : Warning< "'register' storage class specifier is deprecated">, InGroup; +def err_missed_parenthesis_around_typename : Error< + "missed parenthesis around the type name in %0">; def err_expected_case_before_expression: Error< "expected 'case' keyword before expression">; diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 847b074d5c..582721cf40 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -1589,6 +1589,28 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok, // If the operand doesn't start with an '(', it must be an expression. if (Tok.isNot(tok::l_paren)) { + // If construct allows a form without parenthesis, user may forget to put + // pathenthesis around type name. + if (OpTok.is(tok::kw_sizeof) || OpTok.is(tok::kw___alignof) || + OpTok.is(tok::kw_alignof) || OpTok.is(tok::kw__Alignof)) { + bool isAmbiguousTypeId; + if (isTypeIdInParens(isAmbiguousTypeId)) { + DeclSpec DS(AttrFactory); + ParseSpecifierQualifierList(DS); + Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); + ParseDeclarator(DeclaratorInfo); + + SourceLocation LParenLoc = PP.getLocForEndOfToken(OpTok.getLocation()); + SourceLocation RParenLoc = PP.getLocForEndOfToken(PrevTokLocation); + Diag(LParenLoc, diag::err_missed_parenthesis_around_typename) + << OpTok.getName() + << FixItHint::CreateInsertion(LParenLoc, "(") + << FixItHint::CreateInsertion(RParenLoc, ")"); + isCastExpr = true; + return ExprEmpty(); + } + } + isCastExpr = false; if (OpTok.is(tok::kw_typeof) && !getLangOpts().CPlusPlus) { Diag(Tok,diag::err_expected_lparen_after_id) << OpTok.getIdentifierInfo(); diff --git a/test/CXX/dcl.dcl/dcl.attr/dcl.align/p7.cpp b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p7.cpp index 93b1c6461a..05a3926867 100644 --- a/test/CXX/dcl.dcl/dcl.attr/dcl.align/p7.cpp +++ b/test/CXX/dcl.dcl/dcl.attr/dcl.align/p7.cpp @@ -14,3 +14,7 @@ template struct Y { static_assert(alignof(Y) == alignof(int), ""); static_assert(alignof(Y) == alignof(int), ""); // expected-note {{in instantiation of}} + +void pr16992 () { + int x = alignof int; // expected-error{{missed parenthesis around the type name in alignof}} +} diff --git a/test/CXX/expr/expr.unary/expr.sizeof/p1.cpp b/test/CXX/expr/expr.unary/expr.sizeof/p1.cpp index 77d786568b..cd0747fce5 100644 --- a/test/CXX/expr/expr.unary/expr.sizeof/p1.cpp +++ b/test/CXX/expr/expr.unary/expr.sizeof/p1.cpp @@ -26,3 +26,23 @@ void test2() { x = sizeof(test2()); // expected-error {{invalid application of 'sizeof' to an incomplete type 'void'}} x = sizeof(test2); // expected-error {{invalid application of 'sizeof' to a function type}} } + +namespace pr16992 { + +template struct ABC { + int func () { + return sizeof T; //expected-error{{missed parenthesis around the type name in sizeof}} + } +}; + +ABC qq; + +template struct ABC2 { + int func () { + return sizeof T::A; + } +}; + +struct QQ { int A; }; +ABC2 qq2; +} diff --git a/test/Parser/expressions.c b/test/Parser/expressions.c index 0d1b6c945c..6c567f91ba 100644 --- a/test/Parser/expressions.c +++ b/test/Parser/expressions.c @@ -57,3 +57,13 @@ void test7() { ({} // expected-note {{to match}} ; // expected-error {{expected ')'}} } + +// PR16992 +struct pr16992 { int x; }; + +void func_16992 () { + int x1 = sizeof int; // expected-error{{missed parenthesis around the type name in sizeof}} + int x2 = sizeof struct pr16992; // expected-error{{missed parenthesis around the type name in sizeof}} + int x3 = __alignof int; // expected-error{{missed parenthesis around the type name in __alignof}} + int x4 = _Alignof int; // expected-error{{missed parenthesis around the type name in _Alignof}} +}