forked from OSchip/llvm-project
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:
parent
016be42362
commit
aa57a64ef6
|
@ -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">;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue