From f8e3a726f00d920e2910811c0dd58f5a7f422834 Mon Sep 17 00:00:00 2001 From: Oleg Ranevskyy Date: Wed, 30 Mar 2016 21:30:30 +0000 Subject: [PATCH] [Clang][ARM] __va_list declaration is not saved in ASTContext causing compilation error or crash Summary: When the code is compiled for arm32 and the builtin `__va_list` declaration is created by `CreateAAPCSABIBuiltinVaListDecl`, the declaration is not saved in the `ASTContext` which may lead to a compilation error or crash. Minimal reproducer I was able to find: **header.h** ``` #include typedef va_list va_list_1; ``` **test.cpp** ``` typedef __builtin_va_list va_list_2; void foo(const char* format, ...) { va_list args; va_start( args, format ); } ``` Steps to reproduce: ``` clang -x c++-header --target=armv7l-linux-eabihf header.h clang -c -include header.h --target=armv7l-linux-eabihf test.cpp ``` Compilation error: ``` error: non-const lvalue reference to type '__builtin_va_list' cannot bind to a value of unrelated type 'va_list' (aka '__builtin_va_list') ``` Compiling the same code as a C source leads to a crash: ``` clang --target=armv7l-linux-eabihf header.h clang -c -x c -include header.h --target=armv7l-linux-eabihf test.cpp ``` Reviewers: logan, rsmith Subscribers: cfe-commits, asl, aemerson, rengolin Differential Revision: http://reviews.llvm.org/D18557 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@264930 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ASTContext.cpp | 1 + test/PCH/Inputs/__va_list_tag-typedef.h | 4 ++++ test/PCH/__va_list_tag-typedef.c | 14 ++++++++++++++ 3 files changed, 19 insertions(+) create mode 100644 test/PCH/Inputs/__va_list_tag-typedef.h create mode 100644 test/PCH/__va_list_tag-typedef.c diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 5fb94e1d44..77e5087b8c 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -6389,6 +6389,7 @@ CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) { // }; VaListDecl->completeDefinition(); + Context->VaListTagDecl = VaListDecl; // typedef struct __va_list __builtin_va_list; QualType T = Context->getRecordType(VaListDecl); diff --git a/test/PCH/Inputs/__va_list_tag-typedef.h b/test/PCH/Inputs/__va_list_tag-typedef.h new file mode 100644 index 0000000000..33dc6ad484 --- /dev/null +++ b/test/PCH/Inputs/__va_list_tag-typedef.h @@ -0,0 +1,4 @@ +// Header for PCH test __va_list_tag-typedef.c + +#include +typedef va_list va_list_1; diff --git a/test/PCH/__va_list_tag-typedef.c b/test/PCH/__va_list_tag-typedef.c new file mode 100644 index 0000000000..c3745ca2cb --- /dev/null +++ b/test/PCH/__va_list_tag-typedef.c @@ -0,0 +1,14 @@ +// This test checks the patch for the compilation error / crash described in D18557. + +// Test as a C source +// RUN: %clang_cc1 -emit-pch -x c-header -o %t %S/Inputs/__va_list_tag-typedef.h +// RUN: %clang_cc1 -fsyntax-only -include-pch %t %s + +// Test as a C++ source +// RUN: %clang_cc1 -emit-pch -x c++-header -o %t %S/Inputs/__va_list_tag-typedef.h +// RUN: %clang_cc1 -x c++ -fsyntax-only -include-pch %t %s + +// expected-no-diagnostics + +typedef __builtin_va_list va_list_2; +void test(const char* format, ...) { va_list args; va_start( args, format ); } -- 2.40.0