r257608 - Revert "[analyzer] Provide .def-files and visitors for SVal/SymExpr/MemRegion."
Artem Dergachev via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 13 07:52:25 PST 2016
Author: dergachev
Date: Wed Jan 13 09:52:25 2016
New Revision: 257608
URL: http://llvm.org/viewvc/llvm-project?rev=257608&view=rev
Log:
Revert "[analyzer] Provide .def-files and visitors for SVal/SymExpr/MemRegion."
This reverts commit r257605.
The test fails on architectures that use unsigned int as size_t.
SymbolManager.h fails with compile errors on some platforms.
Removed:
cfe/trunk/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def
cfe/trunk/test/Analysis/explain-svals.cpp
Modified:
cfe/trunk/docs/analyzer/DebugChecks.rst
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
Modified: cfe/trunk/docs/analyzer/DebugChecks.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/analyzer/DebugChecks.rst?rev=257608&r1=257607&r2=257608&view=diff
==============================================================================
--- cfe/trunk/docs/analyzer/DebugChecks.rst (original)
+++ cfe/trunk/docs/analyzer/DebugChecks.rst Wed Jan 13 09:52:25 2016
@@ -162,41 +162,6 @@ ExprInspection checks
} while(0); // expected-warning{{SYMBOL DEAD}}
-- void clang_analyzer_explain(a single argument of any type);
-
- This function explains the value of its argument in a human-readable manner
- in the warning message. You can make as many overrides of its prototype
- in the test code as necessary to explain various integral, pointer,
- or even record-type values.
-
- Example usage::
-
- void clang_analyzer_explain(int);
- void clang_analyzer_explain(void *);
-
- void foo(int param, void *ptr) {
- clang_analyzer_explain(param); // expected-warning{{argument 'param'}}
- if (!ptr)
- clang_analyzer_explain(ptr); // expected-warning{{memory address '0'}}
- }
-
-- size_t clang_analyzer_getExtent(void *);
-
- This function returns the value that represents the extent of a memory region
- pointed to by the argument. This value is often difficult to obtain otherwise,
- because no valid code that produces this value. However, it may be useful
- for testing purposes, to see how well does the analyzer model region extents.
-
- Example usage::
-
- void foo() {
- int x, *y;
- size_t xs = clang_analyzer_getExtent(&x);
- clang_analyzer_explain(xs); // expected-warning{{'4'}}
- size_t ys = clang_analyzer_getExtent(&y);
- clang_analyzer_explain(ys); // expected-warning{{'8'}}
- }
-
Statistics
==========
Removed: cfe/trunk/include/clang/StaticAnalyzer/Checkers/SValExplainer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/SValExplainer.h?rev=257607&view=auto
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/SValExplainer.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/SValExplainer.h (removed)
@@ -1,233 +0,0 @@
-//== SValExplainer.h - Symbolic value explainer -----------------*- C++ -*--==//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines SValExplainer, a class for pretty-printing a
-// human-readable description of a symbolic value. For example,
-// "reg_$0<x>" is turned into "initial value of variable 'x'".
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_SVALEXPLAINER_H
-#define LLVM_CLANG_STATICANALYZER_CHECKERS_SVALEXPLAINER_H
-
-#include "clang/AST/DeclCXX.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h"
-
-namespace clang {
-
-namespace ento {
-
-class SValExplainer : public FullSValVisitor<SValExplainer, std::string> {
-private:
- ASTContext &ACtx;
-
- std::string printStmt(const Stmt *S) {
- std::string Str;
- llvm::raw_string_ostream OS(Str);
- S->printPretty(OS, nullptr, PrintingPolicy(ACtx.getLangOpts()));
- return OS.str();
- }
-
- bool isThisObject(const SymbolicRegion *R) {
- if (auto S = dyn_cast<SymbolRegionValue>(R->getSymbol()))
- if (isa<CXXThisRegion>(S->getRegion()))
- return true;
- return false;
- }
-
-public:
- SValExplainer(ASTContext &Ctx) : ACtx(Ctx) {}
-
- std::string VisitUnknownVal(UnknownVal V) {
- return "unknown value";
- }
-
- std::string VisitUndefinedVal(UndefinedVal V) {
- return "undefined value";
- }
-
- std::string VisitLocMemRegionVal(loc::MemRegionVal V) {
- const MemRegion *R = V.getRegion();
- // Avoid the weird "pointer to pointee of ...".
- if (auto SR = dyn_cast<SymbolicRegion>(R)) {
- // However, "pointer to 'this' object" is fine.
- if (!isThisObject(SR))
- return Visit(SR->getSymbol());
- }
- return "pointer to " + Visit(R);
- }
-
- std::string VisitLocConcreteInt(loc::ConcreteInt V) {
- llvm::APSInt I = V.getValue();
- std::string Str;
- llvm::raw_string_ostream OS(Str);
- OS << "concrete memory address '" << I << "'";
- return OS.str();
- }
-
- std::string VisitNonLocSymbolVal(nonloc::SymbolVal V) {
- return Visit(V.getSymbol());
- }
-
- std::string VisitNonLocConcreteInt(nonloc::ConcreteInt V) {
- llvm::APSInt I = V.getValue();
- std::string Str;
- llvm::raw_string_ostream OS(Str);
- OS << (I.isSigned() ? "signed " : "unsigned ") << I.getBitWidth()
- << "-bit integer '" << I << "'";
- return OS.str();
- }
-
- std::string VisitNonLocLazyCompoundVal(nonloc::LazyCompoundVal V) {
- return "lazily frozen compound value of " + Visit(V.getRegion());
- }
-
- std::string VisitSymbolRegionValue(const SymbolRegionValue *S) {
- const MemRegion *R = S->getRegion();
- // Special handling for argument values.
- if (auto V = dyn_cast<VarRegion>(R))
- if (auto D = dyn_cast<ParmVarDecl>(V->getDecl()))
- return "argument '" + D->getQualifiedNameAsString() + "'";
- return "initial value of " + Visit(R);
- }
-
- std::string VisitSymbolConjured(const SymbolConjured *S) {
- return "symbol of type '" + S->getType().getAsString() +
- "' conjured at statement '" + printStmt(S->getStmt()) + "'";
- }
-
- std::string VisitSymbolDerived(const SymbolDerived *S) {
- return "value derived from (" + Visit(S->getParentSymbol()) +
- ") for " + Visit(S->getRegion());
- }
-
- std::string VisitSymbolExtent(const SymbolExtent *S) {
- return "extent of " + Visit(S->getRegion());
- }
-
- std::string VisitSymbolMetadata(const SymbolMetadata *S) {
- return "metadata of type '" + S->getType().getAsString() + "' tied to " +
- Visit(S->getRegion());
- }
-
- std::string VisitSymIntExpr(const SymIntExpr *S) {
- std::string Str;
- llvm::raw_string_ostream OS(Str);
- OS << "(" << Visit(S->getLHS()) << ") "
- << std::string(BinaryOperator::getOpcodeStr(S->getOpcode())) << " "
- << S->getRHS();
- return OS.str();
- }
-
- // TODO: IntSymExpr doesn't appear in practice.
- // Add the relevant code once it does.
-
- std::string VisitSymSymExpr(const SymSymExpr *S) {
- return "(" + Visit(S->getLHS()) + ") " +
- std::string(BinaryOperator::getOpcodeStr(S->getOpcode())) +
- " (" + Visit(S->getRHS()) + ")";
- }
-
- // TODO: SymbolCast doesn't appear in practice.
- // Add the relevant code once it does.
-
- std::string VisitSymbolicRegion(const SymbolicRegion *R) {
- // Explain 'this' object here.
- // TODO: Explain CXXThisRegion itself, find a way to test it.
- if (isThisObject(R))
- return "'this' object";
- return "pointee of " + Visit(R->getSymbol());
- }
-
- std::string VisitAllocaRegion(const AllocaRegion *R) {
- return "region allocated by '" + printStmt(R->getExpr()) + "'";
- }
-
- std::string VisitCompoundLiteralRegion(const CompoundLiteralRegion *R) {
- return "compound literal " + printStmt(R->getLiteralExpr());
- }
-
- std::string VisitStringRegion(const StringRegion *R) {
- return "string literal " + R->getString();
- }
-
- std::string VisitElementRegion(const ElementRegion *R) {
- std::string Str;
- llvm::raw_string_ostream OS(Str);
- OS << "element of type '" << R->getElementType().getAsString()
- << "' with index ";
- // For concrete index: omit type of the index integer.
- if (auto I = R->getIndex().getAs<nonloc::ConcreteInt>())
- OS << I->getValue();
- else
- OS << "'" << Visit(R->getIndex()) << "'";
- OS << " of " + Visit(R->getSuperRegion());
- return OS.str();
- }
-
- std::string VisitVarRegion(const VarRegion *R) {
- const VarDecl *VD = R->getDecl();
- std::string Name = VD->getQualifiedNameAsString();
- if (isa<ParmVarDecl>(VD))
- return "parameter '" + Name + "'";
- else if (VD->hasLocalStorage())
- return "local variable '" + Name + "'";
- else if (VD->isStaticLocal())
- return "static local variable '" + Name + "'";
- else if (VD->hasGlobalStorage())
- return "global variable '" + Name + "'";
- else
- llvm_unreachable("A variable is either local or global");
- }
-
- std::string VisitFieldRegion(const FieldRegion *R) {
- return "field '" + R->getDecl()->getNameAsString() + "' of " +
- Visit(R->getSuperRegion());
- }
-
- std::string VisitCXXTempObjectRegion(const CXXTempObjectRegion *R) {
- return "temporary object constructed at statement '" +
- printStmt(R->getExpr()) + "'";
- }
-
- std::string VisitCXXBaseObjectRegion(const CXXBaseObjectRegion *R) {
- return "base object '" + R->getDecl()->getQualifiedNameAsString() +
- "' inside " + Visit(R->getSuperRegion());
- }
-
- std::string VisitSVal(SVal V) {
- std::string Str;
- llvm::raw_string_ostream OS(Str);
- OS << V;
- return "a value unsupported by the explainer: (" +
- std::string(OS.str()) + ")";
- }
-
- std::string VisitSymExpr(SymbolRef S) {
- std::string Str;
- llvm::raw_string_ostream OS(Str);
- S->dumpToStream(OS);
- return "a symbolic expression unsupported by the explainer: (" +
- std::string(OS.str()) + ")";
- }
-
- std::string VisitMemRegion(const MemRegion *R) {
- std::string Str;
- llvm::raw_string_ostream OS(Str);
- OS << R;
- return "a memory region unsupported by the explainer (" +
- std::string(OS.str()) + ")";
- }
-};
-
-} // end namespace ento
-
-} // end namespace clang
-
-#endif
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h?rev=257608&r1=257607&r2=257608&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h Wed Jan 13 09:52:25 2016
@@ -79,11 +79,48 @@ class MemRegion : public llvm::FoldingSe
friend class MemRegionManager;
public:
enum Kind {
-#define REGION(Id, Parent) Id ## Kind,
-#define REGION_RANGE(Id, First, Last) BEGIN_##Id = First, END_##Id = Last,
-#include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
+ // Memory spaces.
+ CodeSpaceRegionKind,
+ StackLocalsSpaceRegionKind,
+ StackArgumentsSpaceRegionKind,
+ HeapSpaceRegionKind,
+ UnknownSpaceRegionKind,
+ StaticGlobalSpaceRegionKind,
+ GlobalInternalSpaceRegionKind,
+ GlobalSystemSpaceRegionKind,
+ GlobalImmutableSpaceRegionKind,
+ BEGIN_NON_STATIC_GLOBAL_MEMSPACES = GlobalInternalSpaceRegionKind,
+ END_NON_STATIC_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind,
+ BEGIN_GLOBAL_MEMSPACES = StaticGlobalSpaceRegionKind,
+ END_GLOBAL_MEMSPACES = GlobalImmutableSpaceRegionKind,
+ BEGIN_MEMSPACES = CodeSpaceRegionKind,
+ END_MEMSPACES = GlobalImmutableSpaceRegionKind,
+ // Untyped regions.
+ SymbolicRegionKind,
+ AllocaRegionKind,
+ // Typed regions.
+ BEGIN_TYPED_REGIONS,
+ FunctionCodeRegionKind = BEGIN_TYPED_REGIONS,
+ BlockCodeRegionKind,
+ BlockDataRegionKind,
+ BEGIN_TYPED_VALUE_REGIONS,
+ CompoundLiteralRegionKind = BEGIN_TYPED_VALUE_REGIONS,
+ CXXThisRegionKind,
+ StringRegionKind,
+ ObjCStringRegionKind,
+ ElementRegionKind,
+ // Decl Regions.
+ BEGIN_DECL_REGIONS,
+ VarRegionKind = BEGIN_DECL_REGIONS,
+ FieldRegionKind,
+ ObjCIvarRegionKind,
+ END_DECL_REGIONS = ObjCIvarRegionKind,
+ CXXTempObjectRegionKind,
+ CXXBaseObjectRegionKind,
+ END_TYPED_VALUE_REGIONS = CXXBaseObjectRegionKind,
+ END_TYPED_REGIONS = CXXBaseObjectRegionKind
};
-
+
private:
const Kind kind;
@@ -349,7 +386,8 @@ public:
static bool classof(const MemRegion *R) {
Kind k = R->getKind();
- return k >= BEGIN_STACK_MEMSPACES && k <= END_STACK_MEMSPACES;
+ return k >= StackLocalsSpaceRegionKind &&
+ k <= StackArgumentsSpaceRegionKind;
}
};
@@ -511,7 +549,7 @@ public:
static bool classof(const MemRegion* R) {
Kind k = R->getKind();
- return k >= BEGIN_CODE_TEXT_REGIONS && k <= END_CODE_TEXT_REGIONS;
+ return k >= FunctionCodeRegionKind && k <= BlockCodeRegionKind;
}
};
Removed: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def?rev=257607&view=auto
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Regions.def (removed)
@@ -1,89 +0,0 @@
-//===-- Regions.def - Metadata about MemRegion kinds ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// The list of regions (MemRegion sub-classes) used in the Static Analyzer.
-// In order to use this information, users of this file must define one or more
-// of the three macros:
-//
-// REGION(Id, Parent) - for specific MemRegion sub-classes, reserving
-// enum value IdKind for their kind.
-//
-// ABSTRACT_REGION(Id, Parent) - for abstract region classes,
-//
-// REGION_RANGE(Id, First, Last) - for ranges of kind-enums,
-// allowing to determine abstract class of a region
-// based on the kind-enum value.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef REGION
-#define REGION(Id, Parent)
-#endif
-
-#ifndef ABSTRACT_REGION
-#define ABSTRACT_REGION(Id, Parent)
-#endif
-
-#ifndef REGION_RANGE
-#define REGION_RANGE(Id, First, Last)
-#endif
-
-ABSTRACT_REGION(MemSpaceRegion, MemRegion)
- REGION(CodeSpaceRegion, MemSpaceRegion)
- ABSTRACT_REGION(GlobalsSpaceRegion, MemSpaceRegion)
- ABSTRACT_REGION(NonStaticGlobalSpaceRegion, GlobalsSpaceRegion)
- REGION(GlobalImmutableSpaceRegion, NonStaticGlobalSpaceRegion)
- REGION(GlobalInternalSpaceRegion, NonStaticGlobalSpaceRegion)
- REGION(GlobalSystemSpaceRegion, NonStaticGlobalSpaceRegion)
- REGION_RANGE(NON_STATIC_GLOBAL_MEMSPACES, GlobalImmutableSpaceRegionKind,
- GlobalSystemSpaceRegionKind)
- REGION(StaticGlobalSpaceRegion, MemSpaceRegion)
- REGION_RANGE(GLOBAL_MEMSPACES, GlobalImmutableSpaceRegionKind,
- StaticGlobalSpaceRegionKind)
- REGION(HeapSpaceRegion, MemSpaceRegion)
- ABSTRACT_REGION(StackSpaceRegion, MemSpaceRegion)
- REGION(StackArgumentsSpaceRegion, StackSpaceRegion)
- REGION(StackLocalsSpaceRegion, StackSpaceRegion)
- REGION_RANGE(STACK_MEMSPACES, StackArgumentsSpaceRegionKind,
- StackLocalsSpaceRegionKind)
- REGION(UnknownSpaceRegion, MemSpaceRegion)
- REGION_RANGE(MEMSPACES, CodeSpaceRegionKind,
- UnknownSpaceRegionKind)
-ABSTRACT_REGION(SubRegion, MemRegion)
- REGION(AllocaRegion, SubRegion)
- REGION(SymbolicRegion, SubRegion)
- ABSTRACT_REGION(TypedRegion, SubRegion)
- REGION(BlockDataRegion, TypedRegion)
- ABSTRACT_REGION(CodeTextRegion, TypedRegion)
- REGION(BlockCodeRegion, CodeTextRegion)
- REGION(FunctionCodeRegion, CodeTextRegion)
- REGION_RANGE(CODE_TEXT_REGIONS, BlockCodeRegionKind,
- FunctionCodeRegionKind)
- ABSTRACT_REGION(TypedValueRegion, TypedRegion)
- REGION(CompoundLiteralRegion, TypedValueRegion)
- REGION(CXXBaseObjectRegion, TypedValueRegion)
- REGION(CXXTempObjectRegion, TypedValueRegion)
- REGION(CXXThisRegion, TypedValueRegion)
- ABSTRACT_REGION(DeclRegion, TypedValueRegion)
- REGION(FieldRegion, DeclRegion)
- REGION(ObjCIvarRegion, DeclRegion)
- REGION(VarRegion, DeclRegion)
- REGION_RANGE(DECL_REGIONS, FieldRegionKind,
- VarRegionKind)
- REGION(ElementRegion, TypedValueRegion)
- REGION(ObjCStringRegion, TypedValueRegion)
- REGION(StringRegion, TypedValueRegion)
- REGION_RANGE(TYPED_VALUE_REGIONS, CompoundLiteralRegionKind,
- StringRegionKind)
- REGION_RANGE(TYPED_REGIONS, BlockDataRegionKind,
- StringRegionKind)
-
-#undef REGION_RANGE
-#undef ABSTRACT_REGION
-#undef REGION
Removed: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h?rev=257607&view=auto
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SValVisitor.h (removed)
@@ -1,151 +0,0 @@
-//===--- SValVisitor.h - Visitor for SVal subclasses ------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the SValVisitor, SymExprVisitor, and MemRegionVisitor
-// interfaces, and also FullSValVisitor, which visits all three hierarchies.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALVISITOR_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_SVALVISITOR_H
-
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
-
-namespace clang {
-
-namespace ento {
-
-/// SValVisitor - this class implements a simple visitor for SVal
-/// subclasses.
-template <typename ImplClass, typename RetTy = void> class SValVisitor {
-public:
-
-#define DISPATCH(NAME, CLASS) \
- return static_cast<ImplClass *>(this)->Visit ## NAME(V.castAs<CLASS>())
-
- RetTy Visit(SVal V) {
- // Dispatch to VisitFooVal for each FooVal.
- // Take namespaces (loc:: and nonloc::) into account.
- switch (V.getBaseKind()) {
-#define BASIC_SVAL(Id, Parent) case SVal::Id ## Kind: DISPATCH(Id, Id);
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
- case SVal::LocKind:
- switch (V.getSubKind()) {
-#define LOC_SVAL(Id, Parent) \
- case loc::Id ## Kind: DISPATCH(Loc ## Id, loc :: Id);
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
- }
- llvm_unreachable("Unknown Loc sub-kind!");
- case SVal::NonLocKind:
- switch (V.getSubKind()) {
-#define NONLOC_SVAL(Id, Parent) \
- case nonloc::Id ## Kind: DISPATCH(NonLoc ## Id, nonloc :: Id);
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
- }
- llvm_unreachable("Unknown NonLoc sub-kind!");
- }
- llvm_unreachable("Unknown SVal kind!");
- }
-
-#define BASIC_SVAL(Id, Parent) \
- RetTy Visit ## Id(Id V) { DISPATCH(Parent, Id); }
-#define ABSTRACT_SVAL(Id, Parent) \
- BASIC_SVAL(Id, Parent)
-#define LOC_SVAL(Id, Parent) \
- RetTy VisitLoc ## Id(loc::Id V) { DISPATCH(Parent, Parent); }
-#define NONLOC_SVAL(Id, Parent) \
- RetTy VisitNonLoc ## Id(nonloc::Id V) { DISPATCH(Parent, Parent); }
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
-
- // Base case, ignore it. :)
- RetTy VisitSVal(SVal V) { return RetTy(); }
-
-#undef DISPATCH
-};
-
-/// SymExprVisitor - this class implements a simple visitor for SymExpr
-/// subclasses.
-template <typename ImplClass, typename RetTy = void> class SymExprVisitor {
-public:
-
-#define DISPATCH(CLASS) \
- return static_cast<ImplClass *>(this)->Visit ## CLASS(cast<CLASS>(S))
-
- RetTy Visit(SymbolRef S) {
- // Dispatch to VisitSymbolFoo for each SymbolFoo.
- switch (S->getKind()) {
-#define SYMBOL(Id, Parent) \
- case SymExpr::Id ## Kind: DISPATCH(Id);
-#include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def"
- }
- llvm_unreachable("Unknown SymExpr kind!");
- }
-
- // If the implementation chooses not to implement a certain visit method, fall
- // back on visiting the superclass.
-#define SYMBOL(Id, Parent) RetTy Visit ## Id(const Id *S) { DISPATCH(Parent); }
-#define ABSTRACT_SYMBOL(Id, Parent) SYMBOL(Id, Parent)
-#include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def"
-
- // Base case, ignore it. :)
- RetTy VisitSymExpr(SymbolRef S) { return RetTy(); }
-
-#undef DISPATCH
-};
-
-/// MemRegionVisitor - this class implements a simple visitor for MemRegion
-/// subclasses.
-template <typename ImplClass, typename RetTy = void> class MemRegionVisitor {
-public:
-
-#define DISPATCH(CLASS) \
- return static_cast<ImplClass *>(this)->Visit ## CLASS(cast<CLASS>(R))
-
- RetTy Visit(const MemRegion *R) {
- // Dispatch to VisitFooRegion for each FooRegion.
- switch (R->getKind()) {
-#define REGION(Id, Parent) case MemRegion::Id ## Kind: DISPATCH(Id);
-#include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
- }
- llvm_unreachable("Unknown MemRegion kind!");
- }
-
- // If the implementation chooses not to implement a certain visit method, fall
- // back on visiting the superclass.
-#define REGION(Id, Parent) \
- RetTy Visit ## Id(const Id *R) { DISPATCH(Parent); }
-#define ABSTRACT_REGION(Id, Parent) \
- REGION(Id, Parent)
-#include "clang/StaticAnalyzer/Core/PathSensitive/Regions.def"
-
- // Base case, ignore it. :)
- RetTy VisitMemRegion(const MemRegion *R) { return RetTy(); }
-
-#undef DISPATCH
-};
-
-/// FullSValVisitor - a convenient mixed visitor for all three:
-/// SVal, SymExpr and MemRegion subclasses.
-template <typename ImplClass, typename RetTy = void>
-class FullSValVisitor : public SValVisitor<ImplClass, RetTy>,
- public SymExprVisitor<ImplClass, RetTy>,
- public MemRegionVisitor<ImplClass, RetTy> {
-public:
- using SValVisitor<ImplClass, RetTy>::Visit;
- using SymExprVisitor<ImplClass, RetTy>::Visit;
- using MemRegionVisitor<ImplClass, RetTy>::Visit;
-};
-
-} // end namespace ento
-
-} // end namespace clang
-
-#endif
Removed: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def?rev=257607&view=auto
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.def (removed)
@@ -1,74 +0,0 @@
-//===-- SVals.def - Metadata about SVal kinds -------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// The list of symbolic values (SVal kinds and sub-kinds) used in the Static
-// Analyzer. The distinction between loc:: and nonloc:: SVal namespaces is
-// currently hardcoded, because it is too peculiar and explicit to be handled
-// uniformly. In order to use this information, users of this file must define
-// one or more of the following macros:
-//
-// BASIC_SVAL(Id, Parent) - for specific SVal sub-kinds, which are
-// neither in loc:: nor in nonloc:: namespace; these classes occupy
-// their own base kind IdKind.
-//
-// ABSTRACT_SVAL(Id, Parent) - for abstract SVal classes which are
-// neither in loc:: nor in nonloc:: namespace,
-//
-// ABSTRACT_SVAL_WITH_KIND(Id, Parent) - for SVal classes which are also
-// neither in loc:: nor in nonloc:: namespace, but occupy a whole base kind
-// identifier IdKind, much like BASIC_SVALs.
-//
-// LOC_SVAL(Id, Parent) - for values in loc:: namespace, which occupy a sub-kind
-// loc::IdKind.
-//
-// NONLOC_SVAL(Id, Parent) - for values in nonloc:: namespace, which occupy a
-// sub-kind nonloc::IdKind.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef BASIC_SVAL
-#define BASIC_SVAL(Id, Parent)
-#endif
-
-#ifndef ABSTRACT_SVAL
-#define ABSTRACT_SVAL(Id, Parent)
-#endif
-
-#ifndef ABSTRACT_SVAL_WITH_KIND
-#define ABSTRACT_SVAL_WITH_KIND(Id, Parent) ABSTRACT_SVAL(Id, Parent)
-#endif
-
-#ifndef LOC_SVAL
-#define LOC_SVAL(Id, Parent)
-#endif
-
-#ifndef NONLOC_SVAL
-#define NONLOC_SVAL(Id, Parent)
-#endif
-
-BASIC_SVAL(UndefinedVal, SVal)
-ABSTRACT_SVAL(DefinedOrUnknownSVal, SVal)
- BASIC_SVAL(UnknownVal, DefinedOrUnknownSVal)
- ABSTRACT_SVAL(DefinedSVal, DefinedOrUnknownSVal)
- ABSTRACT_SVAL_WITH_KIND(Loc, DefinedSVal)
- LOC_SVAL(ConcreteInt, Loc)
- LOC_SVAL(GotoLabel, Loc)
- LOC_SVAL(MemRegionVal, Loc)
- ABSTRACT_SVAL_WITH_KIND(NonLoc, DefinedSVal)
- NONLOC_SVAL(CompoundVal, NonLoc)
- NONLOC_SVAL(ConcreteInt, NonLoc)
- NONLOC_SVAL(LazyCompoundVal, NonLoc)
- NONLOC_SVAL(LocAsInteger, NonLoc)
- NONLOC_SVAL(SymbolVal, NonLoc)
-
-#undef NONLOC_SVAL
-#undef LOC_SVAL
-#undef ABSTRACT_SVAL_WITH_KIND
-#undef ABSTRACT_SVAL
-#undef BASIC_SVAL
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h?rev=257608&r1=257607&r2=257608&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h Wed Jan 13 09:52:25 2016
@@ -45,9 +45,11 @@ class SVal {
public:
enum BaseKind {
// The enumerators must be representable using 2 bits.
-#define BASIC_SVAL(Id, Parent) Id ## Kind,
-#define ABSTRACT_SVAL_WITH_KIND(Id, Parent) Id ## Kind,
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
+ UndefinedValKind = 0, // for subclass UndefinedVal (an uninitialized value)
+ UnknownValKind = 1, // for subclass UnknownVal (a void value)
+ LocKind = 2, // for subclass Loc (an L-value)
+ NonLocKind = 3 // for subclass NonLoc (an R-value that's not
+ // an L-value)
};
enum { BaseBits = 2, BaseMask = 0x3 };
@@ -304,10 +306,8 @@ private:
namespace nonloc {
-enum Kind {
-#define NONLOC_SVAL(Id, Parent) Id ## Kind,
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
-};
+enum Kind { ConcreteIntKind, SymbolValKind,
+ LocAsIntegerKind, CompoundValKind, LazyCompoundValKind };
/// \brief Represents symbolic expression.
class SymbolVal : public NonLoc {
@@ -465,10 +465,7 @@ private:
namespace loc {
-enum Kind {
-#define LOC_SVAL(Id, Parent) Id ## Kind,
-#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def"
-};
+enum Kind { GotoLabelKind, MemRegionValKind, ConcreteIntKind };
class GotoLabel : public Loc {
public:
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h?rev=257608&r1=257607&r2=257608&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h Wed Jan 13 09:52:25 2016
@@ -43,10 +43,21 @@ class SymExpr : public llvm::FoldingSetN
virtual void anchor();
public:
enum Kind {
-#define SYMBOL(Id, Parent) Id ## Kind,
-#define SYMBOL_RANGE(Id, First, Last) BEGIN_##Id = First, END_##Id = Last,
-#include "clang/StaticAnalyzer/Core/PathSensitive/Symbols.def"
+ SymbolRegionValueKind,
+ SymbolConjuredKind,
+ SymbolDerivedKind,
+ SymbolExtentKind,
+ SymbolMetadataKind,
+ BEGIN_SYMBOLS = SymbolRegionValueKind,
+ END_SYMBOLS = SymbolMetadataKind,
+ SymIntExprKind,
+ IntSymExprKind,
+ SymSymExprKind,
+ BEGIN_BINARYSYMEXPRS = SymIntExprKind,
+ END_BINARYSYMEXPRS = SymSymExprKind,
+ SymbolCastKind
};
+
private:
Kind K;
Removed: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def?rev=257607&view=auto
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Symbols.def (removed)
@@ -1,55 +0,0 @@
-//===-- Symbols.def - Metadata about SymExpr kinds --------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// The list of symbols (SymExpr sub-classes) used in the Static Analyzer.
-// In order to use this information, users of this file must define
-// one or more of the three macros:
-//
-// SYMBOL(Id, Parent) - for specific SymExpr sub-classes, reserving the
-// IdKind identifier for its kind enumeration value.
-//
-// ABSTRACT_SYMBOL(Id, Parent) - for abstract symbol classes,
-//
-// SYMBOL_RANGE(Id, First, Last) - for ranges of kind-enums,
-// allowing to determine abstract class of a symbol
-// based on the kind enumeration value.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SYMBOL
-#define SYMBOL(Id, Parent)
-#endif
-
-#ifndef ABSTRACT_SYMBOL
-#define ABSTRACT_SYMBOL(Id, Parent)
-#endif
-
-#ifndef SYMBOL_RANGE
-#define SYMBOL_RANGE(Id, First, Last)
-#endif
-
-ABSTRACT_SYMBOL(BinarySymExpr, SymExpr)
- SYMBOL(IntSymExpr, BinarySymExpr)
- SYMBOL(SymIntExpr, BinarySymExpr)
- SYMBOL(SymSymExpr, BinarySymExpr)
-SYMBOL_RANGE(BINARYSYMEXPRS, IntSymExprKind, SymSymExprKind)
-
-SYMBOL(SymbolCast, SymExpr)
-
-ABSTRACT_SYMBOL(SymbolData, SymExpr)
- SYMBOL(SymbolConjured, SymbolData)
- SYMBOL(SymbolDerived, SymbolData)
- SYMBOL(SymbolExtent, SymbolData)
- SYMBOL(SymbolMetadata, SymbolData)
- SYMBOL(SymbolRegionValue, SymbolData)
-SYMBOL_RANGE(SYMBOLS, SymbolConjuredKind, SymbolRegionValueKind)
-
-#undef SYMBOL
-#undef ABSTRACT_SYMBOL
-#undef SYMBOL_RANGE
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp?rev=257608&r1=257607&r2=257608&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp Wed Jan 13 09:52:25 2016
@@ -11,7 +11,6 @@
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-#include "clang/StaticAnalyzer/Checkers/SValExplainer.h"
#include "llvm/ADT/StringSwitch.h"
using namespace clang;
@@ -26,21 +25,17 @@ class ExprInspectionChecker : public Che
void analyzerWarnIfReached(const CallExpr *CE, CheckerContext &C) const;
void analyzerCrash(const CallExpr *CE, CheckerContext &C) const;
void analyzerWarnOnDeadSymbol(const CallExpr *CE, CheckerContext &C) const;
- void analyzerExplain(const CallExpr *CE, CheckerContext &C) const;
- void analyzerGetExtent(const CallExpr *CE, CheckerContext &C) const;
typedef void (ExprInspectionChecker::*FnCheck)(const CallExpr *,
CheckerContext &C) const;
- void reportBug(llvm::StringRef Msg, CheckerContext &C) const;
-
public:
bool evalCall(const CallExpr *CE, CheckerContext &C) const;
void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
};
}
-REGISTER_SET_WITH_PROGRAMSTATE(MarkedSymbols, SymbolRef)
+REGISTER_SET_WITH_PROGRAMSTATE(MarkedSymbols, const void *)
bool ExprInspectionChecker::evalCall(const CallExpr *CE,
CheckerContext &C) const {
@@ -55,8 +50,6 @@ bool ExprInspectionChecker::evalCall(con
&ExprInspectionChecker::analyzerWarnIfReached)
.Case("clang_analyzer_warnOnDeadSymbol",
&ExprInspectionChecker::analyzerWarnOnDeadSymbol)
- .Case("clang_analyzer_explain", &ExprInspectionChecker::analyzerExplain)
- .Case("clang_analyzer_getExtent", &ExprInspectionChecker::analyzerGetExtent)
.Default(nullptr);
if (!Handler)
@@ -98,18 +91,6 @@ static const char *getArgumentValueStrin
}
}
-void ExprInspectionChecker::reportBug(llvm::StringRef Msg,
- CheckerContext &C) const {
- if (!BT)
- BT.reset(new BugType(this, "Checking analyzer assumptions", "debug"));
-
- ExplodedNode *N = C.generateNonFatalErrorNode();
- if (!N)
- return;
-
- C.emitReport(llvm::make_unique<BugReport>(*BT, Msg, N));
-}
-
void ExprInspectionChecker::analyzerEval(const CallExpr *CE,
CheckerContext &C) const {
const LocationContext *LC = C.getPredecessor()->getLocationContext();
@@ -119,12 +100,26 @@ void ExprInspectionChecker::analyzerEval
if (LC->getCurrentStackFrame()->getParent() != nullptr)
return;
- reportBug(getArgumentValueString(CE, C), C);
+ if (!BT)
+ BT.reset(new BugType(this, "Checking analyzer assumptions", "debug"));
+
+ ExplodedNode *N = C.generateNonFatalErrorNode();
+ if (!N)
+ return;
+ C.emitReport(
+ llvm::make_unique<BugReport>(*BT, getArgumentValueString(CE, C), N));
}
void ExprInspectionChecker::analyzerWarnIfReached(const CallExpr *CE,
CheckerContext &C) const {
- reportBug("REACHABLE", C);
+
+ if (!BT)
+ BT.reset(new BugType(this, "Checking analyzer assumptions", "debug"));
+
+ ExplodedNode *N = C.generateNonFatalErrorNode();
+ if (!N)
+ return;
+ C.emitReport(llvm::make_unique<BugReport>(*BT, "REACHABLE", N));
}
void ExprInspectionChecker::analyzerCheckInlined(const CallExpr *CE,
@@ -139,32 +134,14 @@ void ExprInspectionChecker::analyzerChec
if (LC->getCurrentStackFrame()->getParent() == nullptr)
return;
- reportBug(getArgumentValueString(CE, C), C);
-}
-
-void ExprInspectionChecker::analyzerExplain(const CallExpr *CE,
- CheckerContext &C) const {
- if (CE->getNumArgs() == 0)
- reportBug("Missing argument for explaining", C);
-
- SVal V = C.getSVal(CE->getArg(0));
- SValExplainer Ex(C.getASTContext());
- reportBug(Ex.Visit(V), C);
-}
-
-void ExprInspectionChecker::analyzerGetExtent(const CallExpr *CE,
- CheckerContext &C) const {
- if (CE->getNumArgs() == 0)
- reportBug("Missing region for obtaining extent", C);
-
- auto MR = dyn_cast_or_null<SubRegion>(C.getSVal(CE->getArg(0)).getAsRegion());
- if (!MR)
- reportBug("Obtaining extent of a non-region", C);
+ if (!BT)
+ BT.reset(new BugType(this, "Checking analyzer assumptions", "debug"));
- ProgramStateRef State = C.getState();
- State = State->BindExpr(CE, C.getLocationContext(),
- MR->getExtent(C.getSValBuilder()));
- C.addTransition(State);
+ ExplodedNode *N = C.generateNonFatalErrorNode();
+ if (!N)
+ return;
+ C.emitReport(
+ llvm::make_unique<BugReport>(*BT, getArgumentValueString(CE, C), N));
}
void ExprInspectionChecker::analyzerWarnOnDeadSymbol(const CallExpr *CE,
@@ -186,14 +163,20 @@ void ExprInspectionChecker::checkDeadSym
ProgramStateRef State = C.getState();
const MarkedSymbolsTy &Syms = State->get<MarkedSymbols>();
for (auto I = Syms.begin(), E = Syms.end(); I != E; ++I) {
- SymbolRef Sym = *I;
+ SymbolRef Sym = static_cast<SymbolRef>(*I);
if (!SymReaper.isDead(Sym))
continue;
- reportBug("SYMBOL DEAD", C);
- State = State->remove<MarkedSymbols>(Sym);
+ if (!BT)
+ BT.reset(new BugType(this, "Checking analyzer assumptions", "debug"));
+
+ ExplodedNode *N = C.generateNonFatalErrorNode();
+ if (!N)
+ return;
+
+ C.emitReport(llvm::make_unique<BugReport>(*BT, "SYMBOL DEAD", N));
+ C.addTransition(State->remove<MarkedSymbols>(Sym), N);
}
- C.addTransition(State);
}
void ExprInspectionChecker::analyzerCrash(const CallExpr *CE,
Removed: cfe/trunk/test/Analysis/explain-svals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/explain-svals.cpp?rev=257607&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/explain-svals.cpp (original)
+++ cfe/trunk/test/Analysis/explain-svals.cpp (removed)
@@ -1,98 +0,0 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core.builtin,debug.ExprInspection,unix.cstring -verify %s
-
-typedef unsigned long size_t;
-
-struct S {
- struct S3 {
- int y[10];
- };
- struct S2 : S3 {
- int *x;
- } s2[10];
- int z;
-};
-
-
-void clang_analyzer_explain(int);
-void clang_analyzer_explain(void *);
-void clang_analyzer_explain(S);
-
-size_t clang_analyzer_getExtent(void *);
-
-size_t strlen(const char *);
-
-int conjure();
-S conjure_S();
-
-int glob;
-static int stat_glob;
-void *glob_ptr;
-
-// Test strings are regex'ed because we need to match exact string
-// rather than a substring.
-
-void test_1(int param, void *ptr) {
- clang_analyzer_explain(&glob); // expected-warning-re{{{{^pointer to global variable 'glob'$}}}}
- clang_analyzer_explain(param); // expected-warning-re{{{{^argument 'param'$}}}}
- clang_analyzer_explain(ptr); // expected-warning-re{{{{^argument 'ptr'$}}}}
- if (param == 42)
- clang_analyzer_explain(param); // expected-warning-re{{{{^signed 32-bit integer '42'$}}}}
-}
-
-void test_2(char *ptr, int ext) {
- clang_analyzer_explain((void *) "asdf"); // expected-warning-re{{{{^pointer to element of type 'char' with index 0 of string literal "asdf"$}}}}
- clang_analyzer_explain(strlen(ptr)); // expected-warning-re{{{{^metadata of type 'unsigned long' tied to pointee of argument 'ptr'$}}}}
- clang_analyzer_explain(conjure()); // expected-warning-re{{{{^symbol of type 'int' conjured at statement 'conjure\(\)'$}}}}
- clang_analyzer_explain(glob); // expected-warning-re{{{{^value derived from \(symbol of type 'int' conjured at statement 'conjure\(\)'\) for global variable 'glob'$}}}}
- clang_analyzer_explain(glob_ptr); // expected-warning-re{{{{^value derived from \(symbol of type 'int' conjured at statement 'conjure\(\)'\) for global variable 'glob_ptr'$}}}}
- clang_analyzer_explain(clang_analyzer_getExtent(ptr)); // expected-warning-re{{{{^extent of pointee of argument 'ptr'$}}}}
- int *x = new int[ext];
- clang_analyzer_explain(x); // expected-warning-re{{{{^pointer to element of type 'int' with index 0 of pointee of symbol of type 'int \*' conjured at statement 'new int \[ext\]'$}}}}
- // Sic! What gets computed is the extent of the element-region.
- clang_analyzer_explain(clang_analyzer_getExtent(x)); // expected-warning-re{{{{^signed 32-bit integer '4'$}}}}
- delete[] x;
-}
-
-void test_3(S s) {
- clang_analyzer_explain(&s); // expected-warning-re{{{{^pointer to parameter 's'$}}}}
- clang_analyzer_explain(s.z); // expected-warning-re{{{{^initial value of field 'z' of parameter 's'$}}}}
- clang_analyzer_explain(&s.s2[5].y[3]); // expected-warning-re{{{{^pointer to element of type 'int' with index 3 of field 'y' of base object 'S::S3' inside element of type 'struct S::S2' with index 5 of field 's2' of parameter 's'$}}}}
- if (!s.s2[7].x) {
- clang_analyzer_explain(s.s2[7].x); // expected-warning-re{{{{^concrete memory address '0'$}}}}
- // FIXME: we need to be explaining '1' rather than '0' here; not explainer bug.
- clang_analyzer_explain(s.s2[7].x + 1); // expected-warning-re{{{{^concrete memory address '0'$}}}}
- }
-}
-
-void test_4(int x, int y) {
- int z;
- static int stat;
- clang_analyzer_explain(x + 1); // expected-warning-re{{{{^\(argument 'x'\) \+ 1$}}}}
- clang_analyzer_explain(1 + y); // expected-warning-re{{{{^\(argument 'y'\) \+ 1$}}}}
- clang_analyzer_explain(x + y); // expected-warning-re{{{{^unknown value$}}}}
- clang_analyzer_explain(z); // expected-warning-re{{{{^undefined value$}}}}
- clang_analyzer_explain(&z); // expected-warning-re{{{{^pointer to local variable 'z'$}}}}
- clang_analyzer_explain(stat); // expected-warning-re{{{{^signed 32-bit integer '0'$}}}}
- clang_analyzer_explain(&stat); // expected-warning-re{{{{^pointer to static local variable 'stat'$}}}}
- clang_analyzer_explain(stat_glob); // expected-warning-re{{{{^initial value of global variable 'stat_glob'$}}}}
- clang_analyzer_explain(&stat_glob); // expected-warning-re{{{{^pointer to global variable 'stat_glob'$}}}}
- clang_analyzer_explain((int[]){1, 2, 3}); // expected-warning-re{{{{^pointer to element of type 'int' with index 0 of compound literal \(int \[3\]\)\{1, 2, 3\}$}}}}
-}
-
-namespace {
-class C {
- int x[10];
-
-public:
- void test_5(int i) {
- clang_analyzer_explain(this); // expected-warning-re{{{{^pointer to 'this' object$}}}}
- clang_analyzer_explain(&x[i]); // expected-warning-re{{{{^pointer to element of type 'int' with index 'argument 'i'' of field 'x' of 'this' object$}}}}
- clang_analyzer_explain(__builtin_alloca(i)); // expected-warning-re{{{{^pointer to region allocated by '__builtin_alloca\(i\)'$}}}}
- }
-};
-} // end of anonymous namespace
-
-void test_6() {
- clang_analyzer_explain(conjure_S()); // expected-warning-re{{{{^lazily frozen compound value of temporary object constructed at statement 'conjure_S\(\)'$}}}}
- clang_analyzer_explain(conjure_S().z); // expected-warning-re{{{{^value derived from \(symbol of type 'struct S' conjured at statement 'conjure_S\(\)'\) for field 'z' of temporary object constructed at statement 'conjure_S\(\)'$}}}}
-}
More information about the cfe-commits
mailing list