]> granicus.if.org Git - clang/commitdiff
AST: Ensure implicit records have default visibility
authorDavid Majnemer <david.majnemer@gmail.com>
Thu, 15 Jan 2015 08:41:25 +0000 (08:41 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Thu, 15 Jan 2015 08:41:25 +0000 (08:41 +0000)
Types composed with certain implicit record types would have their RTTI
marked as hidden because the implicit record type didn't have any
visibility.

This manifests itself as triggering false positives from tools like
clang's -fsantize=function feature.  The RTTI for a function type's
return type wouldn't match if the return type was an implicit record
type.

Patch by Stephan Bergmann!

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

lib/AST/ASTContext.cpp
test/CodeGenCXX/implicit-record-visibility.cpp [new file with mode: 0644]

index 6b864d0f0ac27e8ef20cfda78d667ab551af5e54..88f6bfba024124bbd6090b2deaf759b580d65c16 100644 (file)
@@ -876,6 +876,8 @@ RecordDecl *ASTContext::buildImplicitRecord(StringRef Name,
     NewDecl = RecordDecl::Create(*this, TK, getTranslationUnitDecl(), Loc, Loc,
                                  &Idents.get(Name));
   NewDecl->setImplicit();
+  NewDecl->addAttr(TypeVisibilityAttr::CreateImplicit(
+      const_cast<ASTContext &>(*this), TypeVisibilityAttr::Default));
   return NewDecl;
 }
 
diff --git a/test/CodeGenCXX/implicit-record-visibility.cpp b/test/CodeGenCXX/implicit-record-visibility.cpp
new file mode 100644 (file)
index 0000000..701a203
--- /dev/null
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -I%S -fvisibility hidden -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s
+
+#include <stdarg.h>
+#include <typeinfo>
+
+// If struct __va_list_tag did not explicitly have default visibility, then
+// under -fvisibility hidden the type of function f, due to its va_list (aka
+// __builtin_va_list, aka __va_list_tag (*)[1]) parameter would be hidden:
+
+// CHECK: @_ZTSFvP13__va_list_tagE = linkonce_odr constant
+// CHECK: @_ZTIFvP13__va_list_tagE = linkonce_odr constant
+void f(va_list) { (void)typeid(f); }