Ignore apparent buffer overruns on external or weak globals. This is a major
authorDuncan Sands <baldrick@free.fr>
Sun, 30 Sep 2012 07:30:10 +0000 (07:30 +0000)
committerDuncan Sands <baldrick@free.fr>
Sun, 30 Sep 2012 07:30:10 +0000 (07:30 +0000)
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

lib/Analysis/Lint.cpp
test/Other/lint.ll

index 9258aeee5505ce9d86d0bc3cb9a2808047bc8a3a..7bd945733b4b1d0e08c5ed3f906f71c978a58887 100644 (file)
@@ -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
index d3ab98872d71ae6e922f6bef74fbe4b76360baf2..78bbbe9e6fa6e5a983c951fb47f71da49a9e4b10 100644 (file)
@@ -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