Add fixits suggesting parenthesis around type name in expressions like sizeof.

This fixes PR16992 - Fixit missing when "sizeof type" found.

llvm-svn: 192200
This commit is contained in:
Serge Pavlov 2013-10-08 16:56:30 +00:00
parent 016be42362
commit aa57a64ef6
5 changed files with 58 additions and 0 deletions

View 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">;

View 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();

View 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}}
}

View 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;
}

View 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}}
}