[PATCH] D45383: Strip reference from a va_list object in C when merging parameter types.

Erich Keane via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 6 11:38:43 PDT 2018


erichkeane created this revision.
erichkeane added reviewers: efriedma, eli.friedman, compnerd, rsmith.
erichkeane added a project: clang.

As reported here: https://bugs.llvm.org/show_bug.cgi?id=37033
Any usage of a builtin function that uses a va_list by reference
will cause an assertion when redeclaring it.

Unfortunately, changing the types seems improper, and it breaks
a number of features for it.

Instead, this patch just strips the reference off in this case 
to ensure that the type is properly compared.


Repository:
  rC Clang

https://reviews.llvm.org/D45383

Files:
  lib/AST/ASTContext.cpp
  test/Sema/va_list_builtin_func_redecl.c
  test/Sema/va_list_builtin_func_redecl_errors.c


Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -8160,6 +8160,19 @@
   if (!rmerge.isNull())
     return rmerge;
 
+  if (!getLangOpts().CPlusPlus) {
+    // Builtins that take a reference to a __builtin_va_list in some cases can be
+    // of the type char*&.  Since this is illegal in C and caught in an assert in
+    // mergeTypes, remove the reference.  The user cannot 'type' a char*&, so this
+    // should be a good assumption.
+    if (const auto *RefTy = lhs->getAs<ReferenceType>()) {
+      QualType VaListTy{getBuiltinVaListDecl()->getTypeForDecl(), 0};
+      if (RefTy->getPointeeType().getCanonicalType() ==
+          VaListTy.getCanonicalType())
+        lhs = RefTy->getPointeeType();
+    }
+  }
+
   return mergeTypes(lhs, rhs, OfBlockPointer, Unqualified);
 }
 
Index: test/Sema/va_list_builtin_func_redecl_errors.c
===================================================================
--- test/Sema/va_list_builtin_func_redecl_errors.c
+++ test/Sema/va_list_builtin_func_redecl_errors.c
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -triple=x86_64-unknown-pc %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple=i386-unknown-pc %s
+
+// expected-error at +2{{conflicting types for '__builtin_va_end'}}
+// expected-note at +1{{'__builtin_va_end' is a builtin with type}}
+void __builtin_va_end(void*);
+
+// expected-error at +2{{conflicting types for '__builtin___vprintf_chk'}}
+// expected-note at +1{{'__builtin___vprintf_chk' is a builtin with type}}
+int __builtin___vprintf_chk(int, const char*, void*);
+
+// expected-warning at +2{{incompatible redeclaration of library function 'vprintf'}}
+// expected-note at +1{{'vprintf' is a builtin with type}}
+int vprintf(const char*, void*);
Index: test/Sema/va_list_builtin_func_redecl.c
===================================================================
--- test/Sema/va_list_builtin_func_redecl.c
+++ test/Sema/va_list_builtin_func_redecl.c
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -triple=x86_64-unknown-pc %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple=i386-unknown-pc %s
+// expected-no-diagnostics
+
+void __builtin_va_end(__builtin_va_list);
+int vprintf(const char*, __builtin_va_list);
+int __builtin___vprintf_chk(int, const char*, __builtin_va_list);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D45383.141392.patch
Type: text/x-patch
Size: 2363 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180406/843ae39e/attachment-0001.bin>


More information about the cfe-commits mailing list