]> granicus.if.org Git - clang/commitdiff
[DeclPrinter] Fix two cases that crash clang -ast-print.
authorArtem Belevich <tra@google.com>
Wed, 17 Jan 2018 19:29:39 +0000 (19:29 +0000)
committerArtem Belevich <tra@google.com>
Wed, 17 Jan 2018 19:29:39 +0000 (19:29 +0000)
Both are related to handling anonymous structures.
* clang didn't handle () around an anonymous struct variable.
* clang also crashed on syntax errors that could lead to other
  syntactic constructs following the declaration of an
  anonymous struct. While the code is invalid, that's not
  a good reason to panic compiler.

Differential Revision: https://reviews.llvm.org/D41788

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

lib/AST/DeclPrinter.cpp
test/Sema/ast-print.c
test/SemaCXX/ast-print-crash.cpp [new file with mode: 0644]

index b792c5920a5536cdc2b5b56d281b54f3ff678bdc..e82144b0ae987de82828e0897593b2f85754927a 100644 (file)
@@ -128,9 +128,7 @@ static QualType GetBaseType(QualType T) {
   // FIXME: This should be on the Type class!
   QualType BaseType = T;
   while (!BaseType->isSpecifierType()) {
-    if (isa<TypedefType>(BaseType))
-      break;
-    else if (const PointerType* PTy = BaseType->getAs<PointerType>())
+    if (const PointerType *PTy = BaseType->getAs<PointerType>())
       BaseType = PTy->getPointeeType();
     else if (const BlockPointerType *BPy = BaseType->getAs<BlockPointerType>())
       BaseType = BPy->getPointeeType();
@@ -144,8 +142,11 @@ static QualType GetBaseType(QualType T) {
       BaseType = RTy->getPointeeType();
     else if (const AutoType *ATy = BaseType->getAs<AutoType>())
       BaseType = ATy->getDeducedType();
+    else if (const ParenType *PTy = BaseType->getAs<ParenType>())
+      BaseType = PTy->desugar();
     else
-      llvm_unreachable("Unknown declarator!");
+      // This must be a syntax error.
+      break;
   }
   return BaseType;
 }
index f701b12209537537c8bd93e44bf33bcc9260f03d..83a08bf245836c56eab2099db880c97646ffc2e0 100644 (file)
@@ -15,6 +15,10 @@ struct blah {
   };
 };
 
+// This used to crash clang.
+struct {
+}(s1);
+
 int foo(const struct blah *b) {
   // CHECK: return b->b;
   return b->b;
diff --git a/test/SemaCXX/ast-print-crash.cpp b/test/SemaCXX/ast-print-crash.cpp
new file mode 100644 (file)
index 0000000..c108f66
--- /dev/null
@@ -0,0 +1,12 @@
+// RUN: not %clang_cc1 -triple %ms_abi_triple -ast-print %s -std=gnu++11 \
+// RUN:     | FileCheck %s
+
+// The test compiles a file with a syntax error which used to cause a crash with
+// -ast-print. Compilation fails due to the syntax error, but compiler should
+// not crash and print out whatever it manager to parse.
+
+// CHECK:      struct {
+// CHECK-NEXT: } dont_crash_on_syntax_error;
+// CHECK-NEXT: decltype(nullptr) p;
+struct {
+} dont_crash_on_syntax_error /* missing ; */ decltype(nullptr) p;