]> granicus.if.org Git - clang/commitdiff
Tighten up Parser::ParseTypeofSpecifier().
authorSteve Naroff <snaroff@apple.com>
Tue, 31 Jul 2007 23:56:32 +0000 (23:56 +0000)
committerSteve Naroff <snaroff@apple.com>
Tue, 31 Jul 2007 23:56:32 +0000 (23:56 +0000)
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

Parse/ParseDecl.cpp
test/Parser/typeof.c

index 6b5215b90c5a74e4af2ebf10d44e211ebd0b8a70..843c6eb1a76e34f55b30a7489bdbc2e078989a96 100644 (file)
@@ -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);
 }
 
index 4829713b272fb92d234dd1bc6648d379c86946db..8556687123c52f5e48606ff5c38810d7e4231b06 100644 (file)
@@ -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 *'}}