]> granicus.if.org Git - clang/commitdiff
Work towards fixing crasher with compound literals...
authorSteve Naroff <snaroff@apple.com>
Thu, 19 Jul 2007 01:06:55 +0000 (01:06 +0000)
committerSteve Naroff <snaroff@apple.com>
Thu, 19 Jul 2007 01:06:55 +0000 (01:06 +0000)
Before this commit, we crashed in ParseBinOp...

[dylan:~/llvm/tools/clang] admin% ../../Debug/bin/clang -parse-ast-check compound_literal.c
SemaExpr.cpp:1298: failed assertion `(rhs != 0) && "ParseBinOp(): missing right expression"'

With this commit, we still crash in the newly added action ParseCompoundLiteral (which is progress:-)

[dylan:~/llvm/tools/clang] admin% ../../Debug/bin/clang -parse-ast-check compound_literal.c
SemaExpr.cpp:478: failed assertion `(Op != 0) && "ParseCompoundLiteral(): missing expression"'

The crash go away once the actions return AST nodes. I will do this in a separate commit.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40032 91177308-0d34-0410-b5e6-96231b3b80d8

Parse/ParseExpr.cpp
Parse/ParseInit.cpp
Sema/Sema.h
Sema/SemaExpr.cpp
include/clang/Parse/Action.h
test/Parser/compound_literal.c [new file with mode: 0644]

index 41f347f9aa2fa4bbf57f5ba197c00c9b03da7ca4..5862e7bd84c9bcc8ae004714e5e80cbfc5f4d17a 100644 (file)
@@ -880,7 +880,8 @@ Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType,
         Diag(OpenLoc, diag::ext_c99_compound_literal);
       Result = ParseInitializer();
       ExprType = CompoundLiteral;
-      // TODO: Build AST for compound literal.
+      if (!Result.isInvalid)
+        return Actions.ParseCompoundLiteral(OpenLoc, Ty, RParenLoc, Result.Val);
     } else if (ExprType == CastExpr) {
       // Note that this doesn't parse the subsequence cast-expression, it just
       // returns the parsed type to the callee.
index 01169d885942a30b8a83b7f106807753d201b0b8..75e1c7356edc750d3cc7276c7469251678a1d196 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "clang/Parse/Parser.h"
 #include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/SmallString.h"
 using namespace clang;
 
 
@@ -152,37 +153,47 @@ Parser::ExprResult Parser::ParseInitializer() {
   
   // We support empty initializers, but tell the user that they aren't using
   // C99-clean code.
-  if (Tok.getKind() == tok::r_brace)
+  if (Tok.getKind() == tok::r_brace) {
     Diag(LBraceLoc, diag::ext_gnu_empty_initializer);
-  else {
-    while (1) {
-      // Parse: designation[opt] initializer
-      
-      // If we know that this cannot be a designation, just parse the nested
-      // initializer directly.
-      ExprResult SubElt;
-      if (!MayBeDesignationStart(Tok.getKind()))
-        SubElt = ParseInitializer();
-      else
-        SubElt = ParseInitializerWithPotentialDesignator();
-      
-      // If we couldn't parse the subelement, bail out.
-      if (SubElt.isInvalid) {
-        SkipUntil(tok::r_brace);
-        return SubElt;
-      }
+    // Match the '}'.
+    return Actions.ParseInitList(LBraceLoc, 0, 0, ConsumeBrace());
+  }
+  llvm::SmallVector<ExprTy*, 8> InitExprs;
+  bool InitExprsOk = true;
+  
+  while (1) {
+    // Parse: designation[opt] initializer
     
-      // If we don't have a comma continued list, we're done.
-      if (Tok.getKind() != tok::comma) break;
-      ConsumeToken();
+    // If we know that this cannot be a designation, just parse the nested
+    // initializer directly.
+    ExprResult SubElt;
+    if (!MayBeDesignationStart(Tok.getKind()))
+      SubElt = ParseInitializer();
+    else
+      SubElt = ParseInitializerWithPotentialDesignator();
+
+    // If we couldn't parse the subelement, bail out.
+    if (SubElt.isInvalid) {
+      InitExprsOk = false;
+      SkipUntil(tok::r_brace);
+      break;
+    } else
+      InitExprs.push_back(SubElt.Val);
       
-      // Handle trailing comma.
-      if (Tok.getKind() == tok::r_brace) break;
-    }    
+    // If we don't have a comma continued list, we're done.
+    if (Tok.getKind() != tok::comma) break;
+    
+    // FIXME: save comma locations.
+    ConsumeToken();
+    
+    // Handle trailing comma.
+    if (Tok.getKind() == tok::r_brace) break;
   }
-  
+  if (InitExprsOk && Tok.getKind() == tok::r_brace)
+    return Actions.ParseInitList(LBraceLoc, &InitExprs[0], InitExprs.size(), 
+                                 ConsumeBrace());
   // Match the '}'.
   MatchRHSPunctuation(tok::r_brace, LBraceLoc);
-  return ExprResult(false);
+  return ExprResult(true); // an error occurred.
 }
 
index f87cee60a98c581b9a55ca126fd49be81c52b9ed..0feddd3b151e94b847d23866675855a12bf265a1 100644 (file)
@@ -245,7 +245,14 @@ public:
   
   virtual ExprResult ParseCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
                                    SourceLocation RParenLoc, ExprTy *Op);
+                                   
+  virtual ExprResult ParseCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty,
+                                          SourceLocation RParenLoc, ExprTy *Op);
   
+  virtual ExprResult ParseInitList(SourceLocation LParenLoc, 
+                                   ExprTy **InitList, unsigned NumInit,
+                                   SourceLocation RParenLoc);
+                                   
   virtual ExprResult ParseBinOp(SourceLocation TokLoc, tok::TokenKind Kind,
                                 ExprTy *LHS,ExprTy *RHS);
   
index 044fb63bf081158cbddc69fed1f3e8985b43e86f..999f29a8ae376693bbb00c920d7fc353f35b0fb4 100644 (file)
@@ -470,6 +470,28 @@ ParseCallExpr(ExprTy *Fn, SourceLocation LParenLoc,
                       RParenLoc);
 }
 
+Action::ExprResult Sema::
+ParseCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty,
+                     SourceLocation RParenLoc, ExprTy *Op) {
+  assert((Ty != 0) && "ParseCompoundLiteral(): missing type");
+  QualType literalType = QualType::getFromOpaquePtr(Ty);
+  assert((Op != 0) && "ParseCompoundLiteral(): missing expression");
+  Expr *literalExpr = static_cast<Expr*>(Op);
+  
+  // FIXME: add semantic analysis (C99 6.5.2.5).
+  return false; // FIXME: instantiate a CompoundLiteralExpr
+}
+
+Action::ExprResult Sema::
+ParseInitList(SourceLocation LParenLoc, ExprTy **InitList, unsigned NumInit,
+              SourceLocation RParenLoc) {
+  // FIXME: add semantic analysis (C99 6.7.8). This involves 
+  // knowledge of the object being intialized. As a result, the code for
+  // doing the semantic analysis will likely be located elsewhere (i.e. in 
+  // consumers of InitListExpr (e.g. ParseDeclarator, ParseCompoundLiteral).
+  return false; // FIXME instantiate an InitListExpr.
+}
+
 Action::ExprResult Sema::
 ParseCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
               SourceLocation RParenLoc, ExprTy *Op) {
index bf5499a081076e637bfc6adcf402101c0eb137cd..4922c9a46384e312407f6a3e611674b4dc37761b 100644 (file)
@@ -332,6 +332,15 @@ public:
     return 0;
   }
   
+  virtual ExprResult ParseCompoundLiteral(SourceLocation LParen, TypeTy *Ty,
+                                          SourceLocation RParen, ExprTy *Op) {
+    return 0;
+  }
+  virtual ExprResult ParseInitList(SourceLocation LParenLoc,
+                                   ExprTy **InitList, unsigned NumInit,
+                                   SourceLocation RParenLoc) {
+    return 0;
+  }
   virtual ExprResult ParseCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
                                    SourceLocation RParenLoc, ExprTy *Op) {
     return 0;
diff --git a/test/Parser/compound_literal.c b/test/Parser/compound_literal.c
new file mode 100644 (file)
index 0000000..ef4576d
--- /dev/null
@@ -0,0 +1,5 @@
+// RUN: clang -parse-ast-check %s
+int main() {
+  char *s;
+  s = (char []){"whatever"}; 
+}