On Thursday 07 August 2014 00:03:27 Olivier Goffart wrote:
> On Wednesday 06 August 2014 14:58:41 Richard Smith wrote:
> > Thanks for the further investigation and testing! Could you recursively
> > create a trivial TypeSourceInfo for the TypeOfTypeLoc case?
> 
> Any hint on how to create them in this part of the code?

Here is the final patch which recursively create the TypeSourceInfo for the 
underlying type.

-- 
Olivier
>From 4392ea0b0a3037ca144e034343cc0fe0a8ccf6c3 Mon Sep 17 00:00:00 2001
From: Olivier Goffart <[email protected]>
Date: Wed, 6 Aug 2014 21:40:46 +0200
Subject: [PATCH] Fix initializing TypeOfTypeLoc

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.
---
 include/clang/AST/TypeLoc.h                   |  2 ++
 lib/AST/TypeLoc.cpp                           |  8 ++++++++
 unittests/Tooling/RecursiveASTVisitorTest.cpp | 11 +++++++++++
 3 files changed, 21 insertions(+)

diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h
index 3648d2a..88dce48 100644
--- a/include/clang/AST/TypeLoc.h
+++ b/include/clang/AST/TypeLoc.h
@@ -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.
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
index 208d695..c069eb0 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/lib/AST/TypeLoc.cpp
@@ -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);
diff --git a/unittests/Tooling/RecursiveASTVisitorTest.cpp b/unittests/Tooling/RecursiveASTVisitorTest.cpp
index a1a93a5..6b17dc5 100644
--- a/unittests/Tooling/RecursiveASTVisitorTest.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTest.cpp
@@ -540,6 +540,17 @@ 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));
+}
+
 TEST(RecursiveASTVisitor, VisitsLambdaExpr) {
   LambdaExprVisitor Visitor;
   Visitor.ExpectMatch("", 1, 12);
-- 
2.0.4

_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to