aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2012-09-30 07:30:10 +0000
committerDuncan Sands <baldrick@free.fr>2012-09-30 07:30:10 +0000
commitb620469223d3135361978668c1f5b0739e5cbaa1 (patch)
tree148088e6c1f60e03eb56818ec01b1407dcfc1327
parent73fab91f2cd5fa3dbe4593506ac4a31aa3faf897 (diff)
downloadexternal_llvm-b620469223d3135361978668c1f5b0739e5cbaa1.zip
external_llvm-b620469223d3135361978668c1f5b0739e5cbaa1.tar.gz
external_llvm-b620469223d3135361978668c1f5b0739e5cbaa1.tar.bz2
Ignore apparent buffer overruns on external or weak globals. This is a major
source of false positives due to globals being declared in a header with some kind of incomplete (small) type, but the actual definition being bigger. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@164912 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/Lint.cpp18
-rw-r--r--test/Other/lint.ll5
2 files changed, 16 insertions, 7 deletions
diff --git a/lib/Analysis/Lint.cpp b/lib/Analysis/Lint.cpp
index 9258aee..7bd9457 100644
--- a/lib/Analysis/Lint.cpp
+++ b/lib/Analysis/Lint.cpp
@@ -430,13 +430,17 @@ void Lint::visitMemoryReference(Instruction &I,
BaseAlign = AI->getAlignment();
if (BaseAlign == 0 && ATy->isSized())
BaseAlign = TD->getABITypeAlignment(ATy);
- } else if (GlobalValue *GV = dyn_cast<GlobalVariable>(Base)) {
- Type *GTy = GV->getType()->getElementType();
- if (GTy->isSized())
- BaseSize = TD->getTypeAllocSize(GTy);
- BaseAlign = GV->getAlignment();
- if (BaseAlign == 0 && GTy->isSized())
- BaseAlign = TD->getABITypeAlignment(GTy);
+ } else if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Base)) {
+ // If the global may be defined differently in another compilation unit
+ // then don't warn about funky memory accesses.
+ if (GV->hasDefinitiveInitializer()) {
+ Type *GTy = GV->getType()->getElementType();
+ if (GTy->isSized())
+ BaseSize = TD->getTypeAllocSize(GTy);
+ BaseAlign = GV->getAlignment();
+ if (BaseAlign == 0 && GTy->isSized())
+ BaseAlign = TD->getABITypeAlignment(GTy);
+ }
}
// Accesses from before the start or after the end of the object are not
diff --git a/test/Other/lint.ll b/test/Other/lint.ll
index d3ab988..78bbbe9 100644
--- a/test/Other/lint.ll
+++ b/test/Other/lint.ll
@@ -9,6 +9,7 @@ declare void @has_noaliases(i32* noalias %p, i32* %q)
declare void @one_arg(i32)
@CG = constant i32 7
+@E = external global i8
define i32 @foo() noreturn {
%buf = alloca i8
@@ -100,6 +101,10 @@ next:
ret i32 0
foo:
+; CHECK-NOT: Undefined behavior: Buffer overflow
+; CHECK-NOT: Memory reference address is misaligned
+ %e = bitcast i8* @E to i64*
+ store i64 0, i64* %e
%z = add i32 0, 0
; CHECK: unreachable immediately preceded by instruction without side effects
unreachable