[cfe-commits] r78342 - in /cfe/trunk: include/clang/Analysis/Support/Optional.h lib/Analysis/RegionStore.cpp test/Analysis/misc-ps-region-store.m test/Analysis/unions-region.m

Ted Kremenek kremenek at apple.com
Thu Aug 6 14:43:55 PDT 2009


Author: kremenek
Date: Thu Aug  6 16:43:54 2009
New Revision: 78342

URL: http://llvm.org/viewvc/llvm-project?rev=78342&view=rev
Log:
Fix a couple false positive "uninitialized value" warnings with RegionStore
involving reasoning about unions (which we don't handle yet).

Added:
    cfe/trunk/include/clang/Analysis/Support/Optional.h
    cfe/trunk/test/Analysis/unions-region.m
Modified:
    cfe/trunk/lib/Analysis/RegionStore.cpp
    cfe/trunk/test/Analysis/misc-ps-region-store.m

Added: cfe/trunk/include/clang/Analysis/Support/Optional.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Support/Optional.h?rev=78342&view=auto

==============================================================================
--- cfe/trunk/include/clang/Analysis/Support/Optional.h (added)
+++ cfe/trunk/include/clang/Analysis/Support/Optional.h Thu Aug  6 16:43:54 2009
@@ -0,0 +1,55 @@
+//===-- Optional.h - Simple variant for passing optional values ---*- C++ -*-=//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file provides Optional, a template class modeled in the spirit of
+//  OCaml's 'opt' variant.  The idea is to strongly type whether or not
+//  a value can be optional.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_ANALYSIS_OPTIONAL
+#define LLVM_CLANG_ANALYSIS_OPTIONAL
+
+namespace clang {
+  
+template<typename T>
+class Optional {
+  const T x;
+  unsigned hasVal : 1;
+public:
+  explicit Optional() : hasVal(false) {}
+  Optional(const T &y) : x(y), hasVal(true) {}
+  
+  static inline Optional create(const T* y) {
+    return y ? Optional(*y) : Optional();
+  }
+  
+  const T* getPointer() const { assert(hasVal); return &x; }
+  
+  operator bool() const { return hasVal; }
+  const T* operator->() const { return getPointer(); } 
+  const T& operator*() const { assert(hasVal); return x; }
+};
+} //end clang namespace
+
+namespace llvm {
+template <typename T>
+struct simplify_type<const ::clang::Optional<T> > {
+  typedef const T* SimpleType;
+  static SimpleType getSimplifiedValue(const ::clang::Optional<T> &Val) {
+    return Val.getPointer();
+  }
+};
+  
+template <typename T>
+struct simplify_type< ::clang::Optional<T> >
+  : public simplify_type<const ::clang::Optional<T> > {};
+} // end llvm namespace
+
+#endif

Modified: cfe/trunk/lib/Analysis/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/RegionStore.cpp?rev=78342&r1=78341&r2=78342&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/RegionStore.cpp (original)
+++ cfe/trunk/lib/Analysis/RegionStore.cpp Thu Aug  6 16:43:54 2009
@@ -18,6 +18,7 @@
 #include "clang/Analysis/PathSensitive/GRState.h"
 #include "clang/Analysis/PathSensitive/GRStateTrait.h"
 #include "clang/Analysis/Analyses/LiveVariables.h"
+#include "clang/Analysis/Support/Optional.h"
 #include "clang/Basic/TargetInfo.h"
 
 #include "llvm/ADT/ImmutableMap.h"
@@ -187,6 +188,11 @@
     
   RegionStoreSubRegionMap *getRegionStoreSubRegionMap(const GRState *state);
   
+  
+  /// getDefaultBinding - Returns an SVal* representing an optional default
+  ///  binding associated with a region and its subregions.
+  Optional<SVal> getDefaultBinding(const GRState *state, const MemRegion *R);
+  
   /// getLValueString - Returns an SVal representing the lvalue of a
   ///  StringLiteral.  Within RegionStore a StringLiteral has an
   ///  associated StringRegion, and the lvalue of a StringLiteral is
@@ -829,6 +835,17 @@
 // Loading values from regions.
 //===----------------------------------------------------------------------===//
 
+Optional<SVal> RegionStoreManager::getDefaultBinding(const GRState *state,
+                                                     const MemRegion *R) {
+  
+  if (R->isBoundable())
+    if (const TypedRegion *TR = dyn_cast<TypedRegion>(R))
+      if (TR->getValueType(getContext())->isUnionType())
+        return UnknownVal();
+
+  return Optional<SVal>::create(state->get<RegionDefaultValue>(R));
+}
+
 static bool IsReinterpreted(QualType RTy, QualType UsedTy, ASTContext &Ctx) {
   RTy = Ctx.getCanonicalType(RTy);
   UsedTy = Ctx.getCanonicalType(UsedTy);
@@ -911,6 +928,10 @@
 
   if (RTy->isStructureType())
     return SValuator::CastResult(state, RetrieveStruct(state, R));
+  
+  // FIXME: Handle unions.
+  if (RTy->isUnionType())
+    return SValuator::CastResult(state, UnknownVal());
 
   if (RTy->isArrayType())
     return SValuator::CastResult(state, RetrieveArray(state, R));
@@ -1109,7 +1130,7 @@
 
   const MemRegion* superR = R->getSuperRegion();
   while (superR) {
-    if (const SVal* D = state->get<RegionDefaultValue>(superR)) {
+    if (const Optional<SVal> &D = getDefaultBinding(state, superR)) {
       if (SymbolRef parentSym = D->getAsSymbol())
         return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R);
 

Modified: cfe/trunk/test/Analysis/misc-ps-region-store.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/misc-ps-region-store.m?rev=78342&r1=78341&r2=78342&view=diff

==============================================================================
--- cfe/trunk/test/Analysis/misc-ps-region-store.m (original)
+++ cfe/trunk/test/Analysis/misc-ps-region-store.m Thu Aug  6 16:43:54 2009
@@ -32,10 +32,12 @@
 
 // PR 2948 (testcase; crash on VisitLValue for union types)
 // http://llvm.org/bugs/show_bug.cgi?id=2948
-
 void checkaccess_union() {
   int ret = 0, status;
-  if (((((__extension__ (((union {  // expected-warning {{ Branch condition evaluates to an uninitialized value.}}
+  // Since RegionStore doesn't handle unions yet,
+  // this branch condition won't be triggered
+  // as involving an uninitialized value.  
+  if (((((__extension__ (((union {  // no-warning
     __typeof (status) __in; int __i;}
     )
     {
@@ -44,7 +46,6 @@
         ret = 1;
 }
 
-
 // Check our handling of fields being invalidated by function calls.
 struct test2_struct { int x; int y; char* s; };
 void test2_helper(struct test2_struct* p);

Added: cfe/trunk/test/Analysis/unions-region.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/unions-region.m?rev=78342&view=auto

==============================================================================
--- cfe/trunk/test/Analysis/unions-region.m (added)
+++ cfe/trunk/test/Analysis/unions-region.m Thu Aug  6 16:43:54 2009
@@ -0,0 +1,32 @@
+// RUN: clang-cc -analyze -checker-cfref -analyzer-store=region -analyzer-constraints=range %s -verify
+
+//===-- unions-region.m ---------------------------------------------------===//
+//
+// This file tests the analyzer's reasoning about unions.
+//
+//===----------------------------------------------------------------------===//
+
+// When using RegionStore, this test case previously had a false positive
+// of a 'pass-by-value argument is uninitialized' warning at the call to
+// 'testA_aux'.
+
+union u_testA {
+  unsigned i;
+  float f;
+};
+ 
+float testA(float f) {
+  int testA_aux(unsigned x);
+  int testA_aux_2(union u_testA z);
+  
+  union u_testA swap;
+  swap.f = f;
+
+  if (testA_aux(swap.i))  // no-warning
+    swap.i = ((swap.i & 0xffff0000) >> 16) | ((swap.i & 0x0000fffff) << 16);
+
+  testA_aux_2(swap); // no-warning
+
+  return swap.f;  
+}
+





More information about the cfe-commits mailing list