From: Steve Naroff Date: Tue, 31 Jul 2007 23:56:32 +0000 (+0000) Subject: Tighten up Parser::ParseTypeofSpecifier(). X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=2cb64ecc8672258eef57c616fa37717e57b78ed0;p=clang Tighten up Parser::ParseTypeofSpecifier(). Add some more tests to typeof.c. Also added a couple of missing "expect" attributes that caused the test to fail. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40656 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Parse/ParseDecl.cpp b/Parse/ParseDecl.cpp index 6b5215b90c..843c6eb1a7 100644 --- a/Parse/ParseDecl.cpp +++ b/Parse/ParseDecl.cpp @@ -354,7 +354,7 @@ void Parser::ParseSpecifierQualifierList(DeclSpec &DS) { /// [GNU] '_Decimal32' /// [GNU] '_Decimal64' /// [GNU] '_Decimal128' -/// [GNU] typeof-specifier [TODO] +/// [GNU] typeof-specifier /// [OBJC] class-name objc-protocol-refs[opt] [TODO] /// [OBJC] typedef-name objc-protocol-refs [TODO] /// [OBJC] objc-protocol-refs [TODO] @@ -1424,24 +1424,30 @@ void Parser::ParseTypeofSpecifier(DeclSpec &DS) { if (isTypeSpecifierQualifier()) { TypeTy *Ty = ParseTypeName(); - const char *PrevSpec = 0; - bool isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, - PrevSpec, Ty); - // FIXME: what we have an invalid type? (or Ty is null) + assert(Ty && "Parser::ParseTypeofSpecifier(): missing type"); + + // Match the ')'. + if (Tok.getKind() == tok::r_paren) { + RParenLoc = ConsumeParen(); + const char *PrevSpec = 0; + if (DS.SetTypeSpecType(DeclSpec::TST_typeofType, StartLoc, PrevSpec, Ty)) + // Duplicate type specifiers (e.g. "int typeof(int)). + Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec); + } else // error + MatchRHSPunctuation(tok::r_paren, LParenLoc); } else { // we have an expression. ExprResult Result = ParseExpression(); - if (Result.isInvalid) { - SkipUntil(tok::r_paren); - } - const char *PrevSpec = 0; - bool isInvalid = DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, - PrevSpec, Result.Val); - // FIXME: what we have an invalid type? (or Result.Val is null) + + // Match the ')'. + if (!Result.isInvalid && Tok.getKind() == tok::r_paren) { + RParenLoc = ConsumeParen(); + const char *PrevSpec = 0; + if (DS.SetTypeSpecType(DeclSpec::TST_typeofExpr, StartLoc, PrevSpec, + Result.Val)) + // Duplicate type specifiers (e.g. "int typeof(int)). + Diag(StartLoc, diag::err_invalid_decl_spec_combination, PrevSpec); + } else // error + MatchRHSPunctuation(tok::r_paren, LParenLoc); } - // Match the ')'. - if (Tok.getKind() == tok::r_paren) - RParenLoc = ConsumeParen(); - else - MatchRHSPunctuation(tok::r_paren, LParenLoc); } diff --git a/test/Parser/typeof.c b/test/Parser/typeof.c index 4829713b27..8556687123 100644 --- a/test/Parser/typeof.c +++ b/test/Parser/typeof.c @@ -5,11 +5,16 @@ typedef int TInt; static void test() { int *pi; + int typeof (int) aIntInt; // expected-error{{cannot combine with previous 'int' declaration specifier}} expected-warning{{extension used}} + short typeof (int) aShortInt; // expected-error{{'short typeof' is invalid}} expected-warning{{extension used}} + int int ttt; // expected-error{{cannot combine with previous 'int' declaration specifier}} typeof(TInt) anInt; // expected-warning{{extension used}} + short TInt eee; // expected-error{{parse error}} + void ary[7] fff; // expected-error{{array has incomplete element type 'void'}} expected-error{{parse error}} + typeof(void ary[7]) anIntError; // expected-warning{{extension used}} expected-error{{expected ')'}} expected-error{{to match this '('}} typeof(const int) aci; // expected-warning{{extension used}} const typeof (*pi) aConstInt; // expected-warning{{extension used}} int xx; - short typeof (*pi) aShortInt; // expected-error{{'short typeof' is invalid}} int *i; i = aci; // expected-warning{{incompatible types assigning 'typeof(int const)' to 'int *'}} i = anInt; // expected-warning{{incompatible types assigning 'typeof(TInt)' to 'int *'}}