Fix PR 2514: Do not flag dead initializations for variables initialized to a constant global variable.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64149 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/CheckDeadStores.cpp b/lib/Analysis/CheckDeadStores.cpp
index d5e5f4c..504de3c 100644
--- a/lib/Analysis/CheckDeadStores.cpp
+++ b/lib/Analysis/CheckDeadStores.cpp
@@ -195,8 +195,21 @@
               // If x is EVER assigned a new value later, don't issue
               // a warning.  This is because such initialization can be
               // due to defensive programming.
-              if (!E->isConstantInitializer(Ctx))
-                Report(V, DeadInit, V->getLocation(), E->getSourceRange());
+              if (E->isConstantInitializer(Ctx))
+                return;
+              
+              // Special case: check for initializations from constant
+              //  variables.
+              //
+              //  e.g. extern const int MyConstant;
+              //       int x = MyConstant;
+              //
+              if (DeclRefExpr *DRE=dyn_cast<DeclRefExpr>(E->IgnoreParenCasts()))
+                if (VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl()))
+                  if (VD->hasGlobalStorage() &&
+                      VD->getType().isConstQualified()) return;
+              
+              Report(V, DeadInit, V->getLocation(), E->getSourceRange());
             }
           }
       }
diff --git a/test/Analysis/dead-stores.c b/test/Analysis/dead-stores.c
index c72bdcf..7d7b369 100644
--- a/test/Analysis/dead-stores.c
+++ b/test/Analysis/dead-stores.c
@@ -147,3 +147,19 @@
 
    return (x = 10); // expected-warning{{Although the value stored to 'x' is used in the enclosing expression, the value is never actually read from 'x'}}
 }
+
+// PR 3514: false positive `dead initialization` warning for init to global
+//  http://llvm.org/bugs/show_bug.cgi?id=3514
+extern const int MyConstant;
+int f19(void) {
+  int x = MyConstant;  // no-warning
+  x = 1;
+  return x;
+}
+
+int f19b(void) { // FIXME: Should this case be considered the same as f19?
+  const int MyConstant = 0;
+  int x = MyConstant; // expected-warning{{never read}}
+  x = 1;
+  return x;  
+}