[cfe-commits] r127666 - in /cfe/trunk: include/clang/Analysis/Analyses/UninitializedValues.h include/clang/Basic/DiagnosticGroups.td include/clang/Basic/DiagnosticSemaKinds.td lib/Analysis/UninitializedValues.cpp lib/Sema/AnalysisBasedWarnings.cpp test/Sema/uninit-variables.c
Ted Kremenek
kremenek at apple.com
Mon Mar 14 21:57:38 PDT 2011
Author: kremenek
Date: Mon Mar 14 23:57:38 2011
New Revision: 127666
URL: http://llvm.org/viewvc/llvm-project?rev=127666&view=rev
Log:
Split warnings from -Wuninitialized-experimental into "must-be-initialized" and "may-be-initialized" warnings, each controlled by different flags.
Modified:
cfe/trunk/include/clang/Analysis/Analyses/UninitializedValues.h
cfe/trunk/include/clang/Basic/DiagnosticGroups.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Analysis/UninitializedValues.cpp
cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
cfe/trunk/test/Sema/uninit-variables.c
Modified: cfe/trunk/include/clang/Analysis/Analyses/UninitializedValues.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/UninitializedValues.h?rev=127666&r1=127665&r2=127666&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/Analyses/UninitializedValues.h (original)
+++ cfe/trunk/include/clang/Analysis/Analyses/UninitializedValues.h Mon Mar 14 23:57:38 2011
@@ -29,7 +29,8 @@
virtual ~UninitVariablesHandler();
virtual void handleUseOfUninitVariable(const Expr *ex,
- const VarDecl *vd) {}
+ const VarDecl *vd,
+ bool isAlwaysUninit) {}
};
void runUninitializedVariablesAnalysis(const DeclContext &dc, const CFG &cfg,
Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=127666&r1=127665&r2=127666&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Mon Mar 14 23:57:38 2011
@@ -136,7 +136,8 @@
def Trigraphs : DiagGroup<"trigraphs">;
def : DiagGroup<"type-limits">;
-def Uninitialized : DiagGroup<"uninitialized">;
+
+def UninitializedMaybe : DiagGroup<"uninitialized-maybe">;
def UnknownPragmas : DiagGroup<"unknown-pragmas">;
def UnknownAttributes : DiagGroup<"unknown-attributes">;
def UnnamedTypeTemplateArgs : DiagGroup<"unnamed-type-template-args">;
@@ -199,6 +200,10 @@
UnusedValue, UnusedVariable]>,
DiagCategory<"Unused Entity Issue">;
+def Uninitialized : DiagGroup<"uninitialized",
+ [UninitializedMaybe]>,
+ DiagCategory<"Uninitialized Value Issues">;
+
// Format settings.
def FormatSecurity : DiagGroup<"format-security">;
def Format : DiagGroup<"format",
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=127666&r1=127665&r2=127666&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Mar 14 23:57:38 2011
@@ -868,11 +868,17 @@
InGroup<Uninitialized>;
def warn_uninit_var : Warning<"variable %0 is possibly uninitialized when used here">,
InGroup<DiagGroup<"uninitialized-experimental">>, DefaultIgnore;
+def warn_maybe_uninit_var :
+ Warning<"variable %0 is possibly uninitialized when used here">,
+ InGroup<UninitializedMaybe>, DefaultIgnore;
def note_uninit_var_def : Note<
"variable %0 is declared here">;
def warn_uninit_var_captured_by_block : Warning<
"variable %0 is possibly uninitialized when captured by block">,
InGroup<DiagGroup<"uninitialized-experimental">>, DefaultIgnore;
+def warn_maybe_uninit_var_captured_by_block : Warning<
+ "variable %0 is possibly uninitialized when captured by block">,
+ InGroup<UninitializedMaybe>, DefaultIgnore;
def note_var_fixit_add_initialization : Note<
"add initialization to silence this warning">;
def err_init_incomplete_type : Error<"initialization of incomplete type %0">;
Modified: cfe/trunk/lib/Analysis/UninitializedValues.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/UninitializedValues.cpp?rev=127666&r1=127665&r2=127666&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/UninitializedValues.cpp (original)
+++ cfe/trunk/lib/Analysis/UninitializedValues.cpp Mon Mar 14 23:57:38 2011
@@ -74,14 +74,26 @@
// CFGBlockValues: dataflow values for CFG blocks.
//====------------------------------------------------------------------------//
-enum Value { Initialized = 0, Uninitialized = 1 };
+// These values are defined in such a way that a merge can be done using
+// a bitwise OR.
+enum Value { Unknown = 0x0, /* 00 */
+ Initialized = 0x1, /* 01 */
+ Uninitialized = 0x2, /* 10 */
+ MayUninitialized = 0x3 /* 11 */ };
+
+static bool isUninitialized(const Value v) {
+ return v >= Uninitialized;
+}
+static bool isAlwaysUninit(const Value v) {
+ return v == Uninitialized;
+}
class ValueVector {
llvm::BitVector vec;
public:
ValueVector() {}
- ValueVector(unsigned size) : vec(size) {}
- void resize(unsigned n) { vec.resize(n); }
+ ValueVector(unsigned size) : vec(size << 1) {}
+ void resize(unsigned n) { vec.resize(n << 1); }
void merge(const ValueVector &rhs) { vec |= rhs.vec; }
bool operator!=(const ValueVector &rhs) const { return vec != rhs.vec; }
void reset() { vec.reset(); }
@@ -96,11 +108,17 @@
~reference() {}
reference &operator=(Value v) {
- vv.vec[idx] = (v == Initialized ? false : true);
+ vv.vec[idx << 1] = (((unsigned) v) & 0x1) ? true : false;
+ vv.vec[(idx << 1) | 1] = (((unsigned) v) & 0x2) ? true : false;
return *this;
}
+ operator Value() {
+ unsigned x = (vv.vec[idx << 1] ? 1 : 0) | (vv.vec[(idx << 1) | 1] ? 2 :0);
+ return (Value) x;
+ }
+
bool operator==(Value v) {
- return vv.vec[idx] == (v == Initialized ? false : true);
+ return v = operator Value();
}
};
@@ -346,7 +364,8 @@
currentVoidCast(0), flagBlockUses(flagBlockUses) {}
const CFG &getCFG() { return cfg; }
- void reportUninit(const DeclRefExpr *ex, const VarDecl *vd);
+ void reportUninit(const DeclRefExpr *ex, const VarDecl *vd,
+ bool isAlwaysUninit);
void VisitBlockExpr(BlockExpr *be);
void VisitDeclStmt(DeclStmt *ds);
@@ -366,8 +385,8 @@
}
void TransferFunctions::reportUninit(const DeclRefExpr *ex,
- const VarDecl *vd) {
- if (handler) handler->handleUseOfUninitVariable(ex, vd);
+ const VarDecl *vd, bool isAlwaysUnit) {
+ if (handler) handler->handleUseOfUninitVariable(ex, vd, isAlwaysUnit);
}
FindVarResult TransferFunctions::findBlockVarDecl(Expr* ex) {
@@ -416,8 +435,9 @@
if (vd->getAttr<BlocksAttr>() || !vd->hasLocalStorage() ||
!isTrackedVar(vd))
continue;
- if (vals[vd] == Uninitialized)
- handler->handleUseOfUninitVariable(be, vd);
+ Value v = vals[vd];
+ if (isUninitialized(v))
+ handler->handleUseOfUninitVariable(be, vd, isAlwaysUninit(v));
}
}
@@ -468,9 +488,9 @@
Visit(bo->getLHS());
ValueVector::reference val = vals[vd];
- if (val == Uninitialized) {
+ if (isUninitialized(val)) {
if (bo->getOpcode() != BO_Assign)
- reportUninit(res.getDeclRefExpr(), vd);
+ reportUninit(res.getDeclRefExpr(), vd, isAlwaysUninit(val));
val = Initialized;
}
return;
@@ -496,10 +516,11 @@
res.getDeclRefExpr());
Visit(uo->getSubExpr());
- ValueVector::reference bit = vals[vd];
- if (bit == Uninitialized) {
- reportUninit(res.getDeclRefExpr(), vd);
- bit = Initialized;
+ ValueVector::reference val = vals[vd];
+ if (isUninitialized(val)) {
+ reportUninit(res.getDeclRefExpr(), vd, isAlwaysUninit(val));
+ // Don't cascade warnings.
+ val = Initialized;
}
return;
}
@@ -526,10 +547,13 @@
SaveAndRestore<const DeclRefExpr*> lastDR(currentDR,
res.getDeclRefExpr());
Visit(ce->getSubExpr());
- if (currentVoidCast != ce && vals[vd] == Uninitialized) {
- reportUninit(res.getDeclRefExpr(), vd);
- // Don't cascade warnings.
- vals[vd] = Initialized;
+ if (currentVoidCast != ce) {
+ Value val = vals[vd];
+ if (isUninitialized(val)) {
+ reportUninit(res.getDeclRefExpr(), vd, isAlwaysUninit(val));
+ // Don't cascade warnings.
+ vals[vd] = Initialized;
+ }
}
return;
}
Modified: cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp?rev=127666&r1=127665&r2=127666&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp (original)
+++ cfe/trunk/lib/Sema/AnalysisBasedWarnings.cpp Mon Mar 14 23:57:38 2011
@@ -377,18 +377,20 @@
// -Wuninitialized
//===----------------------------------------------------------------------===//
+typedef std::pair<const Expr*, bool> UninitUse;
+
namespace {
struct SLocSort {
- bool operator()(const Expr *a, const Expr *b) {
- SourceLocation aLoc = a->getLocStart();
- SourceLocation bLoc = b->getLocStart();
+ bool operator()(const UninitUse &a, const UninitUse &b) {
+ SourceLocation aLoc = a.first->getLocStart();
+ SourceLocation bLoc = b.first->getLocStart();
return aLoc.getRawEncoding() < bLoc.getRawEncoding();
}
};
class UninitValsDiagReporter : public UninitVariablesHandler {
Sema &S;
- typedef llvm::SmallVector<const Expr *, 2> UsesVec;
+ typedef llvm::SmallVector<UninitUse, 2> UsesVec;
typedef llvm::DenseMap<const VarDecl *, UsesVec*> UsesMap;
UsesMap *uses;
@@ -398,7 +400,8 @@
flushDiagnostics();
}
- void handleUseOfUninitVariable(const Expr *ex, const VarDecl *vd) {
+ void handleUseOfUninitVariable(const Expr *ex, const VarDecl *vd,
+ bool isAlwaysUninit) {
if (!uses)
uses = new UsesMap();
@@ -406,7 +409,7 @@
if (!vec)
vec = new UsesVec();
- vec->push_back(ex);
+ vec->push_back(std::make_pair(ex, isAlwaysUninit));
}
void flushDiagnostics() {
@@ -426,13 +429,18 @@
for (UsesVec::iterator vi = vec->begin(), ve = vec->end(); vi != ve; ++vi)
{
- if (const DeclRefExpr *dr = dyn_cast<DeclRefExpr>(*vi)) {
- S.Diag(dr->getLocStart(), diag::warn_uninit_var)
+ const bool isAlwaysUninit = vi->second;
+ if (const DeclRefExpr *dr = dyn_cast<DeclRefExpr>(vi->first)) {
+ S.Diag(dr->getLocStart(),
+ isAlwaysUninit ? diag::warn_uninit_var
+ : diag::warn_maybe_uninit_var)
<< vd->getDeclName() << dr->getSourceRange();
}
else {
- const BlockExpr *be = cast<BlockExpr>(*vi);
- S.Diag(be->getLocStart(), diag::warn_uninit_var_captured_by_block)
+ const BlockExpr *be = cast<BlockExpr>(vi->first);
+ S.Diag(be->getLocStart(),
+ isAlwaysUninit ? diag::warn_uninit_var_captured_by_block
+ : diag::warn_maybe_uninit_var_captured_by_block)
<< vd->getDeclName();
}
Modified: cfe/trunk/test/Sema/uninit-variables.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/uninit-variables.c?rev=127666&r1=127665&r2=127666&view=diff
==============================================================================
--- cfe/trunk/test/Sema/uninit-variables.c (original)
+++ cfe/trunk/test/Sema/uninit-variables.c Mon Mar 14 23:57:38 2011
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -Wuninitialized-experimental -fsyntax-only -fblocks %s -verify
+// RUN: %clang_cc1 -fsyntax-only -Wuninitialized-experimental -Wuninitialized-maybe -fsyntax-only -fblocks %s -verify
int test1() {
int x; // expected-note{{variable 'x' is declared here}} expected-note{{add initialization to silence this warning}}
More information about the cfe-commits
mailing list