]> granicus.if.org Git - clang/commitdiff
Add fixits suggesting parenthesis around type name in expressions like sizeof.
authorSerge Pavlov <sepavloff@gmail.com>
Tue, 8 Oct 2013 16:56:30 +0000 (16:56 +0000)
committerSerge Pavlov <sepavloff@gmail.com>
Tue, 8 Oct 2013 16:56:30 +0000 (16:56 +0000)
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

include/clang/Basic/DiagnosticParseKinds.td
lib/Parse/ParseExpr.cpp
test/CXX/dcl.dcl/dcl.attr/dcl.align/p7.cpp
test/CXX/expr/expr.unary/expr.sizeof/p1.cpp
test/Parser/expressions.c

index 8f5ce698ce61813f9d71a5da0358da1414eb1d5f..71463d53ef355bda379a70a7ffdbab1c023d0888 100644 (file)
@@ -310,6 +310,8 @@ def err_unspecified_vla_size_with_static : Error<
 def warn_deprecated_register : Warning<
   "'register' storage class specifier is deprecated">,
   InGroup<DeprecatedRegister>;
+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">;
index 847b074d5c81c8adb570f9c2b574d312a6aa158b..582721cf40f12c41af4904d9d12e7981426051fd 100644 (file)
@@ -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();
index 93b1c6461a43753b61aa5826227c25da5bb410f6..05a3926867867511320a7b5dab619ed135f997c4 100644 (file)
@@ -14,3 +14,7 @@ template<typename T, typename A, int N> struct Y {
 
 static_assert(alignof(Y<char, int, sizeof(int)>) == alignof(int), "");
 static_assert(alignof(Y<int, char, 1>) == alignof(int), ""); // expected-note {{in instantiation of}}
+
+void pr16992 () {
+  int x = alignof int;  // expected-error{{missed parenthesis around the type name in alignof}}
+}
index 77d786568bdfd90e36ece89c0438af7e1c731e53..cd0747fce59b7b5bff5b4b2cae81f043c27315d0 100644 (file)
@@ -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<typename T> struct ABC {
+  int func () {
+    return sizeof T;  //expected-error{{missed parenthesis around the type name in sizeof}}
+  }
+};
+
+ABC<int> qq;
+
+template<typename T> struct ABC2 {
+  int func () {
+    return sizeof T::A;
+  }
+};
+
+struct QQ { int A; };
+ABC2<QQ> qq2;
+}
index 0d1b6c945c5c0a1aa7dfbaa195638170fe4a5a15..6c567f91baa1c472415e2e6ecd8c2e65b61560ab 100644 (file)
@@ -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}}
+}