forked from OSchip/llvm-project
				
			BasicConstraintManager:
- Fix nonsensical logic in AssumeSymLE. When comparing 'sym <= constant' and the constant is the minimum integer value, add the constraint that 'sym == constant' when the path is deemed feasible. All other cases are feasible. - Improve AssumeSymLT to address <rdar://problem/6407949>. When comparing 'sym < constant' and constant is the minimum integer value we know the path is infeasible. - Add test case for <rdar://problem/6407949>. llvm-svn: 60489
This commit is contained in:
		
							parent
							
								
									3f86b51333
								
							
						
					
					
						commit
						f935cfe277
					
				| 
						 | 
					@ -312,6 +312,13 @@ BasicConstraintManager::AssumeSymEQ(const GRState* St, SymbolID sym,
 | 
				
			||||||
const GRState*
 | 
					const GRState*
 | 
				
			||||||
BasicConstraintManager::AssumeSymLT(const GRState* St, SymbolID sym,
 | 
					BasicConstraintManager::AssumeSymLT(const GRState* St, SymbolID sym,
 | 
				
			||||||
                                    const llvm::APSInt& V, bool& isFeasible) {
 | 
					                                    const llvm::APSInt& V, bool& isFeasible) {
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Is 'V' the smallest possible value?
 | 
				
			||||||
 | 
					  if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isSigned())) {
 | 
				
			||||||
 | 
					    // sym cannot be any value less than 'V'.  This path is infeasible.
 | 
				
			||||||
 | 
					    isFeasible = false;
 | 
				
			||||||
 | 
					    return St;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // FIXME: For now have assuming x < y be the same as assuming sym != V;
 | 
					  // FIXME: For now have assuming x < y be the same as assuming sym != V;
 | 
				
			||||||
  return AssumeSymNE(St, sym, V, isFeasible);
 | 
					  return AssumeSymNE(St, sym, V, isFeasible);
 | 
				
			||||||
| 
						 | 
					@ -345,17 +352,28 @@ const GRState*
 | 
				
			||||||
BasicConstraintManager::AssumeSymLE(const GRState* St, SymbolID sym,
 | 
					BasicConstraintManager::AssumeSymLE(const GRState* St, SymbolID sym,
 | 
				
			||||||
                                    const llvm::APSInt& V, bool& isFeasible) {
 | 
					                                    const llvm::APSInt& V, bool& isFeasible) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // FIXME: Primitive logic for now.  Only reject a path if the value of
 | 
					  // Reject a path if the value of sym is a constant X and !(X <= V).
 | 
				
			||||||
  //  sym is a constant X and !(X <= V).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (const llvm::APSInt* X = getSymVal(St, sym)) {
 | 
					  if (const llvm::APSInt* X = getSymVal(St, sym)) {
 | 
				
			||||||
    isFeasible = *X <= V;
 | 
					    isFeasible = *X <= V;
 | 
				
			||||||
    return St;
 | 
					    return St;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  isFeasible = !isNotEqual(St, sym, V) || 
 | 
					  // Sym is not a constant, but it is worth looking to see if V is the
 | 
				
			||||||
               (V != llvm::APSInt::getMinValue(V.getBitWidth(), V.isSigned()));
 | 
					  // minimum integer value.
 | 
				
			||||||
  
 | 
					  if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isSigned())) {
 | 
				
			||||||
 | 
					    // If we know that sym != V, then this condition is infeasible since
 | 
				
			||||||
 | 
					    // there is no other value less than V.    
 | 
				
			||||||
 | 
					    isFeasible = !isNotEqual(St, sym, V);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // If the path is still feasible then as a consequence we know that
 | 
				
			||||||
 | 
					    // 'sym == V' because we cannot have 'sym < V' (no smaller values).
 | 
				
			||||||
 | 
					    // Add this constraint.
 | 
				
			||||||
 | 
					    if (isFeasible)
 | 
				
			||||||
 | 
					      return AddEQ(St, sym, V);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    isFeasible = true;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
  return St;
 | 
					  return St;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -134,3 +134,13 @@ int* f10(int* p, signed char x, int y) {
 | 
				
			||||||
  return p;
 | 
					  return p;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Test case from <rdar://problem/6407949>
 | 
				
			||||||
 | 
					void f11(unsigned i) {
 | 
				
			||||||
 | 
					  int *x = 0;
 | 
				
			||||||
 | 
					  if (i >= 0) {
 | 
				
			||||||
 | 
					    // always true
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    *x = 42; // no-warning
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue