[ASan] Add metadata to renamed instructions so ASan doesn't use the i… (#119387)
…ncorrect name Clang needs variables to be represented with unique names. This means that if a variable shadows another, its given a different name internally to ensure it has a unique name. If ASan tries to use this name when printing an error, it will print the modified unique name, rather than the variable's source code name Fixes #47326
This commit is contained in:
@@ -143,6 +143,9 @@ llvm::AllocaInst *CodeGenFunction::CreateTempAlloca(llvm::Type *Ty,
|
||||
Alloca =
|
||||
new llvm::AllocaInst(Ty, CGM.getDataLayout().getAllocaAddrSpace(),
|
||||
ArraySize, Name, AllocaInsertPt->getIterator());
|
||||
if (SanOpts.Mask & SanitizerKind::Address) {
|
||||
Alloca->addAnnotationMetadata({"alloca_name_altered", Name.str()});
|
||||
}
|
||||
if (Allocas) {
|
||||
Allocas->Add(Alloca);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// RUN: %clangxx_asan -O0 %s -o %t
|
||||
// RUN: not %run %t 2>&1 | FileCheck %s
|
||||
|
||||
int main() {
|
||||
int x;
|
||||
{
|
||||
int x;
|
||||
delete &x;
|
||||
}
|
||||
}
|
||||
|
||||
// CHECK: [32, 36) 'x'
|
||||
@@ -27,5 +27,5 @@ int main(int argc, char *argv[]) {
|
||||
// CHECK: Address 0x{{.*}} is located in stack of thread T0 at offset [[OFFSET:[^ ]*]] in frame
|
||||
// CHECK: {{.*}} in main
|
||||
// CHECK: This frame has
|
||||
// CHECK: {{\[}}[[OFFSET]], {{.*}}) 'x.i' (line [[@LINE-15]])
|
||||
// CHECK: {{\[}}[[OFFSET]], {{.*}}) 'x' (line [[@LINE-15]])
|
||||
}
|
||||
|
||||
@@ -3437,6 +3437,29 @@ static void findStoresToUninstrumentedArgAllocas(
|
||||
}
|
||||
}
|
||||
|
||||
static StringRef getAllocaName(AllocaInst *AI) {
|
||||
// Alloca could have been renamed for uniqueness. Its true name will have been
|
||||
// recorded as an annotation.
|
||||
if (AI->hasMetadata(LLVMContext::MD_annotation)) {
|
||||
MDTuple *AllocaAnnotations =
|
||||
cast<MDTuple>(AI->getMetadata(LLVMContext::MD_annotation));
|
||||
for (auto &Annotation : AllocaAnnotations->operands()) {
|
||||
if (!isa<MDTuple>(Annotation))
|
||||
continue;
|
||||
auto AnnotationTuple = cast<MDTuple>(Annotation);
|
||||
for (int Index = 0; Index < AnnotationTuple->getNumOperands(); Index++) {
|
||||
// All annotations are strings
|
||||
auto MetadataString =
|
||||
cast<MDString>(AnnotationTuple->getOperand(Index));
|
||||
if (MetadataString->getString() == "alloca_name_altered")
|
||||
return cast<MDString>(AnnotationTuple->getOperand(Index + 1))
|
||||
->getString();
|
||||
}
|
||||
}
|
||||
}
|
||||
return AI->getName();
|
||||
}
|
||||
|
||||
void FunctionStackPoisoner::processStaticAllocas() {
|
||||
if (AllocaVec.empty()) {
|
||||
assert(StaticAllocaPoisonCallVec.empty());
|
||||
@@ -3477,7 +3500,8 @@ void FunctionStackPoisoner::processStaticAllocas() {
|
||||
SmallVector<ASanStackVariableDescription, 16> SVD;
|
||||
SVD.reserve(AllocaVec.size());
|
||||
for (AllocaInst *AI : AllocaVec) {
|
||||
ASanStackVariableDescription D = {AI->getName().data(),
|
||||
StringRef Name = getAllocaName(AI);
|
||||
ASanStackVariableDescription D = {Name.data(),
|
||||
ASan.getAllocaSizeInBytes(*AI),
|
||||
0,
|
||||
AI->getAlign().value(),
|
||||
|
||||
Reference in New Issue
Block a user