diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index 1854df7c7c0f1..fd596208c5d6e 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -286,6 +286,9 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) { SmallString<256> TyName; if (isa(Ty)) { llvm::MDNode *ScalarMD = getTypeInfoHelper(Ty); + // char-derived pointers alias everything; use the universal pointer node. + if (ScalarMD == getChar()) + return getAnyPtr(PtrDepth); StringRef Name = cast( ScalarMD->getOperand(CodeGenOpts.NewStructPathTBAA ? 2 : 0)) diff --git a/clang/test/CodeGen/tbaa-char-derived-pointers.c b/clang/test/CodeGen/tbaa-char-derived-pointers.c new file mode 100644 index 0000000000000..6c18a8a74a1b2 --- /dev/null +++ b/clang/test/CodeGen/tbaa-char-derived-pointers.c @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -O2 -disable-llvm-passes -emit-llvm -o - %s | FileCheck %s --check-prefixes=CHECK,OLD +// RUN: %clang_cc1 -triple x86_64-linux-gnu -O2 -disable-llvm-passes -emit-llvm -new-struct-path-tbaa -o - %s | FileCheck %s --check-prefixes=CHECK,NEW +// +// char-derived pointers must use the generic "any pN pointer" TBAA node, not a +// distinct "pN omnipotent char" sibling of "pN int" (which would imply NoAlias). + +void char_int_ptr_cast(int ***p) { + char ***c = (char ***)p; + *c = 0; + (void)*p; +} + +// CHECK-LABEL: define dso_local void @char_int_ptr_cast( +// CHECK: store ptr null, ptr {{.*}}, !tbaa !{{[0-9]+}} + +// OLD-DAG: !{{[0-9]+}} = !{!"p2 int", !{{[0-9]+}}, i64 0} +// OLD-DAG: !{{[0-9]+}} = !{!"any p2 pointer", !{{[0-9]+}}, i64 0} + +// NEW-DAG: !{{[0-9]+}} = !{!{{[0-9]+}}, i64 8, !"p2 int"} +// NEW-DAG: !{{[0-9]+}} = !{!{{[0-9]+}}, i64 8, !"any p2 pointer"} + +// CHECK-NOT: !{!"p2 omnipotent char" +// CHECK-NOT: !{!"p3 omnipotent char"