evaluation.
It's not enough to just track the LValueBase that we're evaluating, we
need to also track the path to the objects whose constructors are
running.
This reinstates r360464 (reverted in r360531) with a workaround for an
MSVC bug that previously caused the Windows bots to fail.
llvm-svn: 360537
Reject attempts to call non-static member functions on objects outside
their lifetime in constant expressions.
This is undefined behavior per [class.cdtor]p2.
We continue to allow this for objects whose values are not visible
within the constant evaluation, because there's no way we can tell
whether the access is defined or not, existing code relies on the
ability to make such calls, and every other compiler allows such
calls.
........
Fix handling of objects under construction during constant expression
evaluation.
It's not enough to just track the LValueBase that we're evaluating, we
need to also track the path to the objects whose constructors are
running.
........
Fixes windows buildbots
llvm-svn: 360531
evaluation.
It's not enough to just track the LValueBase that we're evaluating, we
need to also track the path to the objects whose constructors are
running.
llvm-svn: 360464
Summary:
The following code is accepted by Clang 7 and prior but rejected by the upcoming 8 release and in trunk [1]
```
// error {{never produces a constant expression}}
void foo(const char* s) __attribute__((enable_if(__builtin_constant_p(*s) == false, "trap"))) {}
void test() { foo("abc"); }
```
Prior to Clang 8, the call to `__builtin_constant_p` was a constant expression returning false. Currently, it's not a valid constant expression.
The bug is caused because we failed to set `InConstantContext` when attempting to evaluate unevaluated constant expressions.
[1] https://godbolt.org/z/ksAjmq
Reviewers: rsmith, hans, sbenza
Reviewed By: rsmith
Subscribers: kristina, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D59038
llvm-svn: 355743
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
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
an APValue and retrieve it from map Temporaries.
The version number is needed when a single AST node is visited multiple
times and is used to create APValues that are required to be distinct
from each other (for example, MaterializeTemporaryExprs in default
arguments and VarDecls in loops).
rdar://problem/36505742
Differential Revision: https://reviews.llvm.org/D42776
llvm-svn: 329671
When indirect field is initialized with another field, you have
MemberExpr with CXXThisExpr that corresponds to the field's immediate
anonymous parent. But 'this' was referring to the non-anonymous parent.
So when we were building LValue Designator, it was incorrect as it had
wrong starting point. Usage of such designator would cause unexpected
APValue changes and crashes.
The fix is in adjusting 'this' for indirect fields from non-anonymous
parent to the field's immediate parent.
Discovered by OSS-Fuzz:
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4985
rdar://problem/36359187
Reviewers: rsmith, efriedma
Reviewed By: rsmith
Subscribers: cfe-commits, jkorous-apple
Differential Revision: https://reviews.llvm.org/D42498
llvm-svn: 325997
expressions, if their lifetime began during the evaluation of the expression.
This is technically not allowed in C++11, though we could consider permitting
it there too, as an extension.
llvm-svn: 325663
Don't try to map an APSInt addend to an int64_t in pointer arithmetic before
bounds-checking it. This gives more consistent behavior (outside C++11, we
consistently use 2s complement semantics for both pointer and integer overflow
in constant expressions) and fixes some cases where in C++11 we would fail to
properly check for out-of-bounds pointer arithmetic (if the 2s complement
64-bit overflow landed us back in-bounds).
In passing, also fix some cases where we'd perform possibly-overflowing
arithmetic on CharUnits (which have a signed underlying type) during constant
expression evaluation.
llvm-svn: 293595
This fixes various ways to tickle an assertion in constant expression
evaluation when using __int128. Longer term, we need to figure out what should
happen here: either any kind of overflow in offset calculation should result in
a non-constant value or we should truncate to 64 bits. In C++11 onwards, we're
effectively already checking for overflow because we strictly enforce array
bounds checks, but even there some forms of overflow can slip past undetected.
llvm-svn: 293568
Currently, the constexpr evaluator is very conservative about unmodeled
side-effects when we're evaluating an expression in a mode that allows
such side-effects.
This patch makes us note when we might have actually encountered an
unmodeled side-effect, which allows us to be more accurate when we know
an unmodeled side-effect couldn't have occurred.
This patch has been split into two commits; this one primarily
introduces the bits necessary to track whether we might have potentially
hit such a side-effect. The one that actually does the tracking (which
boils down to more or less a rename of keepEvaluatingAfterFailure to
noteFailure) is coming soon.
Differential Revision: http://reviews.llvm.org/D18540
llvm-svn: 270781
lists. Since the fields are inititalized one at a time, using a field with
lower index to initialize a higher indexed field should not be warned on.
llvm-svn: 218339
Introduce CXXStdInitializerListExpr node, representing the implicit
construction of a std::initializer_list<T> object from its underlying array.
The AST representation of such an expression goes from an InitListExpr with a
flag set, to a CXXStdInitializerListExpr containing a MaterializeTemporaryExpr
containing an InitListExpr (possibly wrapped in a CXXBindTemporaryExpr).
This more detailed representation has several advantages, the most important of
which is that the new MaterializeTemporaryExpr allows us to directly model
lifetime extension of the underlying temporary array. Using that, this patch
*drastically* simplifies the IR generation of this construct, provides IR
generation support for nested global initializer_list objects, fixes several
bugs where the destructors for the underlying array would accidentally not get
invoked, and provides constant expression evaluation support for
std::initializer_list objects.
llvm-svn: 183872
handle temporaries which have been lifetime-extended to static storage duration
within constant expressions. This correctly handles nested lifetime extension
(through reference members of aggregates in aggregate initializers) but
non-constant-expression emission hasn't yet been updated to do the same.
llvm-svn: 183283
The most common (non-buggy) case are where such objects are used as
return expressions in bool-returning functions or as boolean function
arguments. In those cases I've used (& added if necessary) a named
function to provide the equivalent (or sometimes negative, depending on
convenient wording) test.
DiagnosticBuilder kept its implicit conversion operator owing to the
prevalent use of it in return statements.
One bug was found in ExprConstant.cpp involving a comparison of two
PointerUnions (PointerUnion did not previously have an operator==, so
instead both operands were converted to bool & then compared). A test
is included in test/SemaCXX/constant-expression-cxx1y.cpp for the fix
(adding operator== to PointerUnion in LLVM).
llvm-svn: 181869
inefficient; we perform a linear scan of switch labels to find the one matching
the condition, and then walk the body looking for that label. Both parts should
be straightforward to optimize.
llvm-svn: 181671
statement in constexpr functions. Everything which doesn't require variable
mutation is also allowed as an extension in C++11. 'void' becomes a literal
type to support constexpr functions which return 'void'.
llvm-svn: 180022