Commit Graph

37 Commits

Author SHA1 Message Date
Artem Dergachev f7887d41cb [analyzer] When failing to evaluate a __builtin_constant_p, presume it's false.
__builtin_constant_p(x) is a compiler builtin that evaluates to 1 when
its argument x is a compile-time constant and to 0 otherwise. In CodeGen
it is simply lowered to the respective LLVM intrinsic. In the Analyzer
we've been trying to delegate modeling to Expr::EvaluateAsInt, which is
allowed to sometimes fail for no apparent reason.

When it fails, let's conservatively return false. Modeling it as false
is pretty much never wrong, and it is only required to return true
on a best-effort basis, which every user should expect.

Fixes VLAChecker false positives on code that tries to emulate
static asserts in C by constructing a VLA of dynamic size -1 under the
assumption that this dynamic size is actually a constant
in the sense of __builtin_constant_p.

Differential Revision: https://reviews.llvm.org/D60110

llvm-svn: 357557
2019-04-03 01:53:40 +00:00
Erik Pilkington 9c3b588db9 Add a new builtin: __builtin_dynamic_object_size
This builtin has the same UI as __builtin_object_size, but has the
potential to be evaluated dynamically. It is meant to be used as a
drop-in replacement for libraries that use __builtin_object_size when
a dynamic checking mode is enabled. For instance,
__builtin_object_size fails to provide any extra checking in the
following function:

  void f(size_t alloc) {
    char* p = malloc(alloc);
    strcpy(p, "foobar"); // expands to __builtin___strcpy_chk(p, "foobar", __builtin_object_size(p, 0))
  }

This is an overflow if alloc < 7, but because LLVM can't fold the
object size intrinsic statically, it folds __builtin_object_size to
-1. With __builtin_dynamic_object_size, alloc is passed through to
__builtin___strcpy_chk.

rdar://32212419

Differential revision: https://reviews.llvm.org/D56760

llvm-svn: 352665
2019-01-30 20:34:53 +00:00
Kristof Umann 058a7a450a [analyzer] Supply all checkers with a shouldRegister function
Introduce the boolean ento::shouldRegister##CHECKERNAME(const LangOptions &LO)
function very similarly to ento::register##CHECKERNAME. This will force every
checker to implement this function, but maybe it isn't that bad: I saw a lot of
ObjC or C++ specific checkers that should probably not register themselves based
on some LangOptions (mine too), but they do anyways.

A big benefit of this is that all registry functions now register their checker,
once it is called, registration is guaranteed.

This patch is a part of a greater effort to reinvent checker registration, more
info here: D54438#1315953

Differential Revision: https://reviews.llvm.org/D55424

llvm-svn: 352277
2019-01-26 14:23:08 +00:00
Chandler Carruth 2946cd7010 Update the file headers across all of the LLVM projects in the monorepo
to reflect the new license.

We understand that people may be surprised that we're moving the header
entirely to discuss the new license. We checked this carefully with the
Foundation's lawyer and we believe this is the correct approach.

Essentially, all code in the project is now made available by the LLVM
project under our new license, so you will see that the license headers
include that license only. Some of our contributors have contributed
code under our old license, and accordingly, we have retained a copy of
our old license notice in the top-level files in each project and
repository.

llvm-svn: 351636
2019-01-19 08:50:56 +00:00
Kristof Umann 76a21502fd [analyzer][NFC] Move CheckerRegistry from the Core directory to Frontend
ClangCheckerRegistry is a very non-obvious, poorly documented, weird concept.
It derives from CheckerRegistry, and is placed in lib/StaticAnalyzer/Frontend,
whereas it's base is located in lib/StaticAnalyzer/Core. It was, from what I can
imagine, used to circumvent the problem that the registry functions of the
checkers are located in the clangStaticAnalyzerCheckers library, but that
library depends on clangStaticAnalyzerCore. However, clangStaticAnalyzerFrontend
depends on both of those libraries.

One can make the observation however, that CheckerRegistry has no place in Core,
it isn't used there at all! The only place where it is used is Frontend, which
is where it ultimately belongs.

This move implies that since
include/clang/StaticAnalyzer/Checkers/ClangCheckers.h only contained a single function:

class CheckerRegistry;

void registerBuiltinCheckers(CheckerRegistry &registry);

it had to re purposed, as CheckerRegistry is no longer available to
clangStaticAnalyzerCheckers. It was renamed to BuiltinCheckerRegistration.h,
which actually describes it a lot better -- it does not contain the registration
functions for checkers, but only those generated by the tblgen files.

Differential Revision: https://reviews.llvm.org/D54436

llvm-svn: 349275
2018-12-15 16:23:51 +00:00
Fangrui Song 407659ab0a Revert "Revert r347417 "Re-Reinstate 347294 with a fix for the failures.""
It seems the two failing tests can be simply fixed after r348037

Fix 3 cases in Analysis/builtin-functions.cpp
Delete the bad CodeGen/builtin-constant-p.c for now

llvm-svn: 348053
2018-11-30 23:41:18 +00:00
Fangrui Song f5d3335d75 Revert r347417 "Re-Reinstate 347294 with a fix for the failures."
Kept the "indirect_builtin_constant_p" test case in test/SemaCXX/constant-expression-cxx1y.cpp
while we are investigating why the following snippet fails:

  extern char extern_var;
  struct { int a; } a = {__builtin_constant_p(extern_var)};

llvm-svn: 348039
2018-11-30 21:26:09 +00:00
Hans Wennborg 48ee4ad325 Re-commit r347417 "Re-Reinstate 347294 with a fix for the failures."
This was reverted in r347656 due to me thinking it caused a miscompile of
Chromium. Turns out it was the Chromium code that was broken.

llvm-svn: 347756
2018-11-28 14:04:12 +00:00
Hans Wennborg 8c79706e89 Revert r347417 "Re-Reinstate 347294 with a fix for the failures."
This caused a miscompile in Chrome (see crbug.com/908372) that's
illustrated by this small reduction:

  static bool f(int *a, int *b) {
    return !__builtin_constant_p(b - a) || (!(b - a));
  }

  int arr[] = {1,2,3};

  bool g() {
    return f(arr, arr + 3);
  }

  $ clang -O2 -S -emit-llvm a.cc -o -

g() should return true, but after r347417 it became false for some reason.

This also reverts the follow-up commits.

r347417:
> Re-Reinstate 347294 with a fix for the failures.
>
> Don't try to emit a scalar expression for a non-scalar argument to
> __builtin_constant_p().
>
> Third time's a charm!

r347446:
> The result of is.constant() is unsigned.

r347480:
> A __builtin_constant_p() returns 0 with a function type.

r347512:
> isEvaluatable() implies a constant context.
>
> Assume that we're in a constant context if we're asking if the expression can
> be compiled into a constant initializer. This fixes the issue where a
> __builtin_constant_p() in a compound literal was diagnosed as not being
> constant, even though it's always possible to convert the builtin into a
> constant.

r347531:
> A "constexpr" is evaluated in a constant context. Make sure this is reflected
> if a __builtin_constant_p() is a part of a constexpr.

llvm-svn: 347656
2018-11-27 14:01:40 +00:00
Bill Wendling 6ff1751f7d Re-Reinstate 347294 with a fix for the failures.
Don't try to emit a scalar expression for a non-scalar argument to
__builtin_constant_p().

Third time's a charm!

llvm-svn: 347417
2018-11-21 20:44:18 +00:00
Nico Weber 9f0246d473 Revert r347364 again, the fix was incomplete.
llvm-svn: 347389
2018-11-21 12:47:43 +00:00
Bill Wendling 91549ed15f Reinstate 347294 with a fix for the failures.
EvaluateAsInt() is sometimes called in a constant context. When that's the
case, we need to specify it as so.

llvm-svn: 347364
2018-11-20 23:24:16 +00:00
Artem Dergachev f3e09bdaee [analyzer] Add support for __builtin_constant_p.
This builtin is evaluated in compile time. But in the analyzer we don't yet
automagically evaluate all calls that can be evaluated in compile time.

Patch by Felix Kostenzer!

Differential Revision: https://reviews.llvm.org/D42745

llvm-svn: 324789
2018-02-10 00:51:47 +00:00
George Karpenkov d703ec94a9 [analyzer] introduce getSVal(Stmt *) helper on ExplodedNode, make sure the helper is used consistently
In most cases using
`N->getState()->getSVal(E, N->getLocationContext())`
is ugly, verbose, and also opens up more surface area for bugs if an
inconsistent location context is used.

This patch introduces a helper on an exploded node, and ensures
consistent usage of either `ExplodedNode::getSVal` or
`CheckContext::getSVal` across the codebase.
As a result, a large number of redundant lines is removed.

Differential Revision: https://reviews.llvm.org/D42155

llvm-svn: 322753
2018-01-17 20:27:29 +00:00
Gabor Horvath b3bcddf769 [analyzer] Do not continue to analyze a path if the constraints contradict with builtin assume
Differential Revision: https://reviews.llvm.org/D34502

llvm-svn: 305991
2017-06-22 10:09:40 +00:00
Gabor Horvath 3a00b41e43 [analyzer] Add modelling of __builtin_assume
Differential Revision: https://reviews.llvm.org/D33092

llvm-svn: 302880
2017-05-12 07:02:54 +00:00
David Majnemer 5116993f8e Add support for __builtin_alloca_with_align
__builtin_alloca always uses __BIGGEST_ALIGNMENT__ for the alignment of
the allocation.  __builtin_alloca_with_align allows the programmer to
specify the alignment of the allocation.

This fixes PR30658.

llvm-svn: 285544
2016-10-31 05:37:48 +00:00
Sanjay Patel a24296b459 add __builtin_unpredictable and convert to metadata
This patch depends on r246688 (D12341).

The goal is to make LLVM generate different code for these functions for a target that
has cheap branches (see PR23827 for more details):

int foo();

int normal(int x, int y, int z) {
   if (x != 0 && y != 0) return foo();
   return 1;
}

int crazy(int x, int y) {
   if (__builtin_unpredictable(x != 0 && y != 0)) return foo();
   return 1;
}

Differential Revision: http://reviews.llvm.org/D12458

llvm-svn: 246699
2015-09-02 20:01:30 +00:00
Jordan Rose 21933ccdd7 Teach the analyzer that __builtin_assume_aligned returns its first argument.
Patch by Daniel Fahlgren!

llvm-svn: 217461
2014-09-09 21:42:16 +00:00
Jordan Rose 5374c07ab9 Omit arguments of __builtin_object_size from the CFG.
This builtin does not actually evaluate its arguments for side effects,
so we shouldn't include them in the CFG. In the analyzer, rely on the
constant expression evaluator to get the proper semantics, at least for
now. (In the future, we could get ambitious and try to provide path-
sensitive size values.)

In theory, this does pose a problem for liveness analysis: a variable can
be used within the __builtin_object_size argument expression but not show
up as live. However, it is very unlikely that such a value would be used
to compute the object size and not used to access the object in some way.

<rdar://problem/14760817>

llvm-svn: 188679
2013-08-19 16:27:28 +00:00
Jordan Rose 78cd51b2ee [analyzer] Add support for __builtin_addressof.
...so we don't regress on std::addressof.

llvm-svn: 186140
2013-07-12 00:26:14 +00:00
David Blaikie 2fdacbc5b0 Replace SVal llvm::cast support to be well-defined.
See r175462 for another example/more details.

llvm-svn: 175594
2013-02-20 05:52:05 +00:00
Chandler Carruth 3a02247dc9 Sort all of Clang's files under 'lib', and fix up the broken headers
uncovered.

This required manually correcting all of the incorrect main-module
headers I could find, and running the new llvm/utils/sort_includes.py
script over the files.

I also manually added quite a few missing headers that were uncovered by
shuffling the order or moving headers up to be main-module-headers.

llvm-svn: 169237
2012-12-04 09:13:33 +00:00
Anna Zaks e3beeaa5e7 [analyzer] Fix a crash reported in PR 14400.
The AllocaRegion did not have the superRegion (based on LocationContext)
as part of it's hash. As a consequence, the AllocaRegions from
different frames were uniqued to be the same region.

llvm-svn: 168599
2012-11-26 19:11:46 +00:00
Ted Kremenek d94854a42e Rename 'currentX' to 'currX' throughout analyzer and libAnalysis.
Also rename 'getCurrentBlockCounter()' to 'blockCount()'.

This ripples a bunch of code simplifications; mostly aesthetic,
but makes the code a bit tighter.

llvm-svn: 162349
2012-08-22 06:26:15 +00:00
Ted Kremenek 49b1e38e4b Change references to 'const ProgramState *' to typedef 'ProgramStateRef'.
At this point this is largely cosmetic, but it opens the door to replace
ProgramStateRef with a smart pointer that more eagerly acts in the role
of reclaiming unused ProgramState objects.

llvm-svn: 149081
2012-01-26 21:29:00 +00:00
Ted Kremenek 632e3b7ee2 [analyzer] Make the entries in 'Environment' context-sensitive by making entries map from
(Stmt*,LocationContext*) pairs to SVals instead of Stmt* to SVals.

This is needed to support basic IPA via inlining.  Without this, we cannot tell
if a Stmt* binding is part of the current analysis scope (StackFrameContext) or
part of a parent context.

This change introduces an uglification of the use of getSVal(), and thus takes
two steps forward and one step back.  There are also potential performance implications
of enlarging the Environment.  Both can be addressed going forward by refactoring the
APIs and optimizing the internal representation of Environment.  This patch
mainly introduces the functionality upon when we want to build upon (and clean up).

llvm-svn: 147688
2012-01-06 22:09:28 +00:00
Anna Zaks c6aa531a8f [analyzer] Refactor checkers to use helper function for getting callee Decl and name.
We are getting name of the called function or it's declaration in a few checkers. Refactor them to use the helper function in the CheckerContext. 

llvm-svn: 145576
2011-12-01 05:57:37 +00:00
Anna Zaks c9abbe2b3e [analyzer] Add getLocationContext to CheckerContext
CheckerContext::getPredecessor is only used to get to the LocationContext
half of the times.

llvm-svn: 143061
2011-10-26 21:06:44 +00:00
Anna Zaks da4c8d6811 [analyzer] Rename generateNode -> addTransition in CheckerContext
Also document addTransition methods.

llvm-svn: 143059
2011-10-26 21:06:34 +00:00
Anna Zaks 23d7ba3579 [analyzer] Removing references to CheckerContext::getNodeBuilder(): checkers can obtain block count directly from the Context.
llvm-svn: 141112
2011-10-04 20:43:05 +00:00
Ted Kremenek 001fd5b498 Rename GRState to ProgramState, and cleanup some code formatting along the way.
llvm-svn: 137665
2011-08-15 22:09:50 +00:00
Argyrios Kyrtzidis 6a5674ffa6 [analyzer] Rename CheckerV2 -> Checker.
llvm-svn: 126726
2011-03-01 01:16:21 +00:00
Argyrios Kyrtzidis f3ed8b631d [analyzer] Migrate BuiltinFunctionChecker to CheckerV2.
llvm-svn: 126611
2011-02-28 01:27:07 +00:00
Ted Kremenek f8cbac4b91 Split 'include/clang/StaticAnalyzer' into 'include/clang/StaticAnalyzer/Core' and 'include/clang/StaticAnalyzer/Checkers'.
This layout matches lib/StaticAnalyzer, which corresponds to two StaticAnalyzer libraries.

llvm-svn: 125251
2011-02-10 01:03:03 +00:00
Argyrios Kyrtzidis f99d595cfd [analyzer] lib/StaticAnalyzer/Checkers/ExprEngineInternalChecks.h -> lib/StaticAnalyzer/Checkers/InternalChecks.h
llvm-svn: 125121
2011-02-08 22:30:02 +00:00
Ted Kremenek d99bd55a5e Chris Lattner has strong opinions about directory
layout.  :)

Rename the 'EntoSA' directories to 'StaticAnalyzer'.

Internally we will still use the 'ento' namespace
for the analyzer engine (unless there are further
sabre rattlings...).

llvm-svn: 122514
2010-12-23 19:38:26 +00:00