Fix initializing TypeOfTypeLoc
authorOlivier Goffart <ogoffart@woboq.com>
Fri, 24 Oct 2014 13:52:55 +0000 (13:52 +0000)
committerOlivier Goffart <ogoffart@woboq.com>
Fri, 24 Oct 2014 13:52:55 +0000 (13:52 +0000)
This fixes a crash in the RecursiveASTVisitor on such code
 __typeof__(struct F*) var[invalid];

The UnderlyingTInfo of a TypeOfTypeLoc was left uninitialized when
created from ASTContext::getTrivialTypeSourceInfo
This lead to a crash in RecursiveASTVisitor when trying to access it.

llvm-svn: 220562

clang/include/clang/AST/TypeLoc.h
clang/lib/AST/TypeLoc.cpp
clang/unittests/Tooling/RecursiveASTVisitorTestTypeLocVisitor.cpp

index e28fe2d..4f3c811 100644 (file)
@@ -1567,6 +1567,8 @@ public:
   void setUnderlyingTInfo(TypeSourceInfo* TI) const {
     this->getLocalData()->UnderlyingTInfo = TI;
   }
+
+  void initializeLocal(ASTContext &Context, SourceLocation Loc);
 };
 
 // FIXME: location of the 'decltype' and parens.
index 208d695..c069eb0 100644 (file)
@@ -312,6 +312,14 @@ TypeLoc TypeLoc::IgnoreParensImpl(TypeLoc TL) {
   return TL;
 }
 
+void TypeOfTypeLoc::initializeLocal(ASTContext &Context,
+                                       SourceLocation Loc) {
+  TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo>
+      ::initializeLocal(Context, Loc);
+  this->getLocalData()->UnderlyingTInfo = Context.getTrivialTypeSourceInfo(
+      getUnderlyingType(), Loc);
+}
+
 void ElaboratedTypeLoc::initializeLocal(ASTContext &Context, 
                                         SourceLocation Loc) {
   setElaboratedKeywordLoc(Loc);
index 22c5883..63e2e8b 100644 (file)
@@ -79,4 +79,15 @@ TEST(RecursiveASTVisitor, VisitsObjCPropertyType) {
       TypeLocVisitor::Lang_OBJC));
 }
 
+TEST(RecursiveASTVisitor, VisitInvalidType) {
+  TypeLocVisitor Visitor;
+  // FIXME: It would be nice to have information about subtypes of invalid type
+  //Visitor.ExpectMatch("typeof(struct F *) []", 1, 1);
+  // Even if the full type is invalid, it should still find sub types
+  //Visitor.ExpectMatch("struct F", 1, 19);
+  EXPECT_FALSE(Visitor.runOver(
+      "__typeof__(struct F*) var[invalid];\n",
+      TypeLocVisitor::Lang_C));
+}
+
 } // end anonymous namespace