r270781 introduced the ability to track whether or not we might have
had unmodeled side-effects during constant expression evaluation. This
patch makes the constexpr evaluator use that tracking.
Reviewed as a part of D18540.
llvm-svn: 270784
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
const' variable. That variable might be defined as 'constexpr', so we cannot
prove that a use of it could never be a constant expression.
llvm-svn: 270774
Restructure the implict floating point to integer conversions so that
interesting sub-groups are under different flags. Breakdown of warnings:
No warning:
Exact conversions from floating point to integer:
int x = 10.0;
int x = 1e10;
-Wliteral-conversion - Floating point literal to integer with rounding:
int x = 5.5;
int x = -3.4;
-Wfloat-conversion - All conversions not covered by the above two:
int x = GetFloat();
int x = 5.5 + 3.5;
-Wfloat-zero-conversion - The expression converted has a non-zero floating
point value that gets converted to a zero integer value, excluded the cases
falling under -Wliteral-conversion. Subset of -Wfloat-conversion.
int x = 1.0 / 2.0;
-Wfloat-overflow-conversion - The floating point value is outside the range
of the integer type, exluding cases from -Wliteral conversion. Subset of
-Wfloat-conversion.
char x = 500;
char x = -1000;
-Wfloat-bool-conversion - Any conversion of a floating point type to bool.
Subset of -Wfloat-conversion.
if (GetFloat()) {}
bool x = 5.0;
-Wfloat-bool-constant-conversion - Conversion of a compile time evaluatable
floating point value to bool. Subset of -Wfloat-bool-conversion.
bool x = 1.0;
bool x = 4.0 / 20.0;
Also add EvaluateAsFloat to Sema, which is similar to EvaluateAsInt, but for
floating point values.
llvm-svn: 267054
Putting OpenCLImageTypes.def to clangAST library violates layering requirement: "It's not OK for a Basic/ header to include an AST/ header".
This fixes the modules build.
Differential revision: http://reviews.llvm.org/D18954
Reviewers: Richard Smith, Vassil Vassilev.
llvm-svn: 266180
I. Current implementation of images is not conformant to spec in the following points:
1. It makes no distinction with respect to access qualifiers and therefore allows to use images with different access type interchangeably. The following code would compile just fine:
void write_image(write_only image2d_t img);
kernel void foo(read_only image2d_t img) { write_image(img); } // Accepted code
which is disallowed according to s6.13.14.
2. It discards access qualifier on generated code, which leads to generated code for the above example:
call void @write_image(%opencl.image2d_t* %img);
In OpenCL2.0 however we can have different calls into write_image with read_only and wite_only images.
Also generally following compiler steps have no easy way to take different path depending on the image access: linking to the right implementation of image types, performing IR opts and backend codegen differently.
3. Image types are language keywords and can't be redeclared s6.1.9, which can happen currently as they are just typedef names.
4. Default access qualifier read_only is to be added if not provided explicitly.
II. This patch corrects the above points as follows:
1. All images are encapsulated into a separate .def file that is inserted in different points where image handling is required. This avoid a lot of code repetition as all images are handled the same way in the code with no distinction of their exact type.
2. The Cartesian product of image types and image access qualifiers is added to the builtin types. This simplifies a lot handling of access type mismatch as no operations are allowed by default on distinct Builtin types. Also spec intended access qualifier as special type qualifier that are combined with an image type to form a distinct type (see statement above - images can't be created w/o access qualifiers).
3. Improves testing of images in Clang.
Author: Anastasia Stulova
Reviewers: bader, mgrang.
Subscribers: pxli168, pekka.jaaskelainen, yaxunl.
Differential Revision: http://reviews.llvm.org/D17821
llvm-svn: 265783
Support the constexpr specifier on lambda expressions - and support its inference from the lambda call operator's body.
i.e.
auto L = [] () constexpr { return 5; };
static_assert(L() == 5); // OK
auto Implicit = [] (auto a) { return a; };
static_assert(Implicit(5) == 5);
We do not support evaluation of lambda's within constant expressions just yet.
Implementation Strategy:
- teach ParseLambdaExpressionAfterIntroducer to expect a constexpr specifier and mark the invented function call operator's declarator's decl-specifier with it; Have it emit fixits for multiple decl-specifiers (mutable or constexpr) in this location.
- for cases where constexpr is not explicitly specified, have buildLambdaExpr check whether the invented function call operator satisfies the requirements of a constexpr function, by calling CheckConstexprFunctionDecl/Body.
Much obliged to Richard Smith for his patience and his care, in ensuring the code is clang-worthy.
llvm-svn: 264513
A member expression's base doesn't always have an impact on what the
member decl would evaluate to. In such a case, the base is used as a
poor man's scope qualifier.
This fixes PR26738.
Differential Revision: http://reviews.llvm.org/D17619
llvm-svn: 261975
This patch fixes the following bugs in __builtin_classify_type implementation:
1) Support for member functions and fields
2) Same behavior as GCC in C mode (specifically, return integer_type_class for
enums and pointer_type_class for function pointers and arrays). Behavior in
C++ mode didn't changed.
Also, it refactors the whole implementation, by replacing a sequence of
if-else-if with a couple of switches.
Differential Revision: http://reviews.llvm.org/D16846
llvm-svn: 260881
Fix a crash while parsing this code:
struct X {
friend constexpr int foo(X*) { return 12; }
static constexpr int j = foo(static_cast<X*>(nullptr));
};
Differential Revision: http://reviews.llvm.org/D16973
llvm-svn: 260675
In {CG,}ExprConstant.cpp, we weren't treating vector splats properly.
This patch makes us treat splats more properly.
Additionally, this patch adds a new cast kind which allows a bool->int
cast to result in -1 or 0, instead of 1 or 0 (for true and false,
respectively), so we can sanely model OpenCL bool->int casts in the AST.
Differential Revision: http://reviews.llvm.org/D14877
llvm-svn: 257559
variables in C, in the cases where we can constant-fold it to a value
regardless (such as floating-point division by zero and signed integer
overflow). Strictly enforcing this rule breaks too much code.
llvm-svn: 254992
to treat as an ICE results in undefined behavior. Instead, return the "natural"
result of the operation (signed wraparound / inf / nan).
llvm-svn: 254699
side-effect, so that we don't allow speculative evaluation of such expressions
during code generation.
This caused a diagnostic quality regression, so fix constant expression
diagnostics to prefer either the first "can't be constant folded" diagnostic or
the first "not a constant expression" diagnostic depending on the kind of
evaluation we're doing. This was always the intent, but didn't quite work
correctly before.
This results in certain initializers that used to be constant initializers to
no longer be; in particular, things like:
float f = 1e100;
are no longer accepted in C. This seems appropriate, as such constructs would
lead to code being executed if sanitizers are enabled.
llvm-svn: 254574
`pass_object_size` is our way of enabling `__builtin_object_size` to
produce high quality results without requiring inlining to happen
everywhere.
A link to the design doc for this attribute is available at the
Differential review link below.
Differential Revision: http://reviews.llvm.org/D13263
llvm-svn: 254554
MSVC supports 'property' attribute and allows to apply it to the declaration of an empty array in a class or structure definition.
For example:
```
__declspec(property(get=GetX, put=PutX)) int x[];
```
The above statement indicates that x[] can be used with one or more array indices. In this case, i=p->x[a][b] will be turned into i=p->GetX(a, b), and p->x[a][b] = i will be turned into p->PutX(a, b, i);
Differential Revision: http://reviews.llvm.org/D13336
llvm-svn: 254067
r246877 made __builtin_object_size substantially more aggressive with
unknown bases if Type=1 or Type=3, which causes issues when we encounter
code like this:
struct Foo {
int a;
char str[1];
};
const char str[] = "Hello, World!";
struct Foo *f = (struct Foo *)malloc(sizeof(*f) + strlen(str));
strcpy(&f->str, str);
__builtin_object_size(&f->str, 1) would hand back 1, which is
technically correct given the type of Foo, but the type of Foo lies to
us about how many bytes are available in this case.
This patch adds support for this "writing off the end" idiom -- we now
answer conservatively when we're given the address of the very last
member in a struct.
Differential Revision: http://reviews.llvm.org/D12169
llvm-svn: 250488
The root cause here is that ObjCSelectorExpr is an rvalue, yet it can have its
address taken. That's kind of awkward, but fixing this is awkward in other
ways, see https://llvm.org/bugs/show_bug.cgi?id=24774#c16 . For now, just
fix the crash.
llvm-svn: 247740
Apparently there are many cast kinds that may cause implicit pointer
arithmetic to happen. In light of this, the cast ignoring logic
introduced in r246877 has been changed to only ignore a small set of
cast kinds, and a test for this behavior has been added.
Thanks to Richard for catching this before it became a bug report. :)
llvm-svn: 246890
Improvements:
- For all types, we would give up in a case such as:
__builtin_object_size((char*)&foo, N);
even if we could provide an answer to
__builtin_object_size(&foo, N);
We now provide the same answer for both of the above examples in all
cases.
- For type=1|3, we now support subobjects with unknown bases, as long
as the designator is valid.
Thanks to Richard Smith for the review + design planning.
Review: http://reviews.llvm.org/D12169
llvm-svn: 246877
We cannot tell if an object is past-the-end if its type is incomplete.
Zero sized objects satisfy past-the-end criteria and our object might
turn out to be such an object.
This fixes PR24622.
llvm-svn: 246359
Adds parsing/sema analysis/serialization/deserialization for array sections in OpenMP constructs (introduced in OpenMP 4.0).
Currently it is allowed to use array sections only in OpenMP clauses that accepts list of expressions.
Differential Revision: http://reviews.llvm.org/D10732
llvm-svn: 245937
__builtin_object_size would return incorrect answers for many uses where
type=3. This fixes the inaccuracy by making us emit 0 instead of LLVM's
objectsize intrinsic.
Additionally, there are many cases where we would emit suboptimal (but
correct) answers, such as when arrays are involved. This patch fixes
some of these cases (please see new tests in test/CodeGen/object-size.c
for specifics on which cases are improved)
Resubmit of r245323 with PR24493 fixed.
Patch mostly by Richard Smith.
Differential Revision: http://reviews.llvm.org/D12000
This fixes PR15212.
llvm-svn: 245403
__builtin_object_size would return incorrect answers for many uses where
type=3. This fixes the inaccuracy by making us emit 0 instead of LLVM's
objectsize intrinsic.
Additionally, there are many cases where we would emit suboptimal (but
correct) answers, such as when arrays are involved. This patch fixes
some of these cases (please see new tests in test/CodeGen/object-size.c
for specifics on which cases are improved)
Patch mostly by Richard Smith.
Differential Revision: http://reviews.llvm.org/D12000
This fixes PR15212.
llvm-svn: 245323
The patch is generated using this command:
$ tools/extra/clang-tidy/tool/run-clang-tidy.py -fix \
-checks=-*,llvm-namespace-comment -header-filter='llvm/.*|clang/.*' \
work/llvm/tools/clang
To reduce churn, not touching namespaces spanning less than 10 lines.
llvm-svn: 240270
Based on previous discussion on the mailing list, clang currently lacks support
for C99 partial re-initialization behavior:
Reference: http://lists.cs.uiuc.edu/pipermail/cfe-dev/2013-April/029188.html
Reference: http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_253.htm
This patch attempts to fix this problem.
Given the following code snippet,
struct P1 { char x[6]; };
struct LP1 { struct P1 p1; };
struct LP1 l = { .p1 = { "foo" }, .p1.x[2] = 'x' };
// this example is adapted from the example for "struct fred x[]" in DR-253;
// currently clang produces in l: { "\0\0x" },
// whereas gcc 4.8 produces { "fox" };
// with this fix, clang will also produce: { "fox" };
Differential Review: http://reviews.llvm.org/D5789
llvm-svn: 239446
Currently, the NaN values emitted for MIPS architectures do not cover
non-IEEE754-2008 compliant case. This change fixes the issue.
Patch by Vladimir Radosavljevic.
Differential Revision: http://reviews.llvm.org/D7882
llvm-svn: 230653
When visiting AssignmentOps, keep evaluating after a failure (when possible) in
order to identify overflow in subexpressions.
Differential Revision: http://reviews.llvm.org/D1238
llvm-svn: 228202
Comparing the address of an object with an incomplete type might return
true with a 'distinct' object if the former has a size of zero.
However, such an object should compare unequal with null.
llvm-svn: 224040
OpenCL v2.0 s6.5.5 restricts conversion of pointers to different address spaces:
- the named address spaces (__global, __local, and __private) => __generic - implicitly converted;
- __generic => named - with an explicit cast;
- named <=> named - disallowed;
- __constant <=> any other - disallowed.
llvm-svn: 222834
This is a new form of expression of the form:
(expr op ... op expr)
where one of the exprs is a parameter pack. It expands into
(expr1 op (expr2onwards op ... op expr))
(and likewise if the pack is on the right). The non-pack operand can be
omitted; in that case, an empty pack gives a fallback value or an error,
depending on the operator.
llvm-svn: 221573
complete object to a pointer to the start of another complete object does
not evaluate to the constant 'false'. All other comparisons between the
addresses of subobjects of distinct complete objects still do.
llvm-svn: 220343
and !=) to support mixed complex and real operand types.
This requires removing an assert from SemaChecking, and adding support
both to the constant evaluator and the code generator to synthesize the
imaginary part when needed. This seemed somewhat cleaner than having
just the comparison operators force real-to-complex conversions.
I've added test cases for these operations. I'm really terrified that
there were *no* tests in-tree which exercised this.
This turned up when trying to build R after my change to the complex
type lowering.
llvm-svn: 219570
operators where one type is a C complex type, and to emit both the
efficient and correct implementation for complex arithmetic according to
C11 Annex G using this extra information.
For both multiply and divide the old code was writing a long-hand
reduced version of the math without any of the special handling of inf
and NaN recommended by the standard here. Instead of putting more
complexity here, this change does what GCC does which is to emit
a libcall for the fully general case.
However, the old code also failed to do the proper minimization of the
set of operations when there was a mixed complex and real operation. In
those cases, C provides a spec for much more minimal operations that are
valid. Clang now emits the exact suggested operations. This change isn't
*just* about performance though, without minimizing these operations, we
again lose the correct handling of infinities and NaNs. It is critical
that this happen in the frontend based on assymetric type operands to
complex math operations.
The performance implications of this change aren't trivial either. I've
run a set of benchmarks in Eigen, an open source mathematics library
that makes heavy use of complex. While a few have slowed down due to the
libcall being introduce, most sped up and some by a huge amount: up to
100% and 140%.
In order to make all of this work, also match the algorithm in the
constant evaluator to the one in the runtime library. Currently it is
a broken port of the simplifications from C's Annex G to the long-hand
formulation of the algorithm.
Splitting this patch up is very hard because none of this works without
the AST change to preserve non-complex operands. Sorry for the enormous
change.
Follow-up changes will include support for sinking the libcalls onto
cold paths in common cases and fastmath improvements to allow more
aggressive backend folding.
Differential Revision: http://reviews.llvm.org/D5698
llvm-svn: 219557
Assertion failed: "Computed __func__ length differs from type!"
Reworked PredefinedExpr representation with internal StringLiteral field for function declaration.
Differential Revision: http://reviews.llvm.org/D5365
llvm-svn: 219393
Richard noted in the review of r217349 that extra handling of
__builtin_assume_aligned inside of the expression evaluator was needed. He was
right, and this should address the concerns raised, namely:
1. The offset argument to __builtin_assume_aligned can have side effects, and
we need to make sure that all arguments are properly evaluated.
2. If the alignment assumption does not hold, that introduces undefined
behavior, and undefined behavior cannot appear inside a constexpr.
and hopefully the diagnostics produced are detailed enough to explain what is
going on.
llvm-svn: 218992
Adding handling of __builtin_assume_aligned to IntExprEvaluator does not make
sense because __builtin_assume_aligned returns a pointer (not an integer).
Thanks to Richard for figuring out why this was not doing anything.
I'll add this back in a better place (PointerExprEvaluator perhaps).
llvm-svn: 218958
constexpr function. Part of this fix is a tentative fix for an as-yet-unfiled
core issue (we're missing a prohibition against reading mutable members from
unions via a trivial constructor/assignment, since that doesn't perform an
lvalue-to-rvalue conversion on the members).
llvm-svn: 217852
This makes use of the recently-added @llvm.assume intrinsic to implement a
__builtin_assume(bool) intrinsic (to provide additional information to the
optimizer). This hooks up __assume in MS-compatibility mode to mirror
__builtin_assume (the semantics have been intentionally kept compatible), and
implements GCC's __builtin_assume_aligned as assume((p - o) & mask == 0). LLVM
now contains special logic to deal with assumptions of this form.
llvm-svn: 217349
Changes diagnostic options, language standard options, diagnostic identifiers, diagnostic wording to use c++14 instead of c++1y. It also modifies related test cases to use the updated diagnostic wording.
llvm-svn: 215982
or a class derived from T. We already supported this when initializing
_Atomic(T) from T for most (and maybe all) other reasonable values of T.
llvm-svn: 214390
The class seems to have an invariant that Entries is non-empty if
Invalid is false. It appears this method was previously private, and
all internal uses checked Invalid. Now there is an external caller, so
check Invalid to avoid array OOB underflow.
Fixes PR20420.
llvm-svn: 213816
This is a follow-up to an IRC conversation with Richard last night; __assume
does not evaluate its argument, and so the argument should not contribute to
whether (__assume(e), constant) can be used where a constant is required.
llvm-svn: 213267
This is a follow-up to David's r211677. For the following code,
we would end up referring to 'foo' in the initializer for 'arr',
and then fail to link, because 'foo' is dllimport and needs to be
accessed through the __imp_?foo.
__declspec(dllimport) extern const char foo[];
const char* f() {
static const char* const arr[] = { foo };
return arr[0];
}
Differential Revision: http://reviews.llvm.org/D4299
llvm-svn: 211736
The C++ language requires that the address of a function be the same
across all translation units. To make __declspec(dllimport) useful,
this means that a dllimported function must also obey this rule. MSVC
implements this by dynamically querying the import address table located
in the linked executable. This means that the address of such a
function in C++ is not constant (which violates other rules).
However, the C language has no notion of ODR nor does it permit dynamic
initialization whatsoever. This requires implementations to _not_
dynamically query the import address table and instead utilize a wrapper
function that will be synthesized by the linker which will eventually
query the import address table. The effect this has is, to say the
least, perplexing.
Consider the following C program:
__declspec(dllimport) void f(void);
typedef void (*fp)(void);
static const fp var = &f;
const fp fun() { return &f; }
int main() { return fun() == var; }
MSVC will statically initialize "var" with the address of the wrapper
function and "fun" returns the address of the actual imported function.
This means that "main" will return false!
Note that LLVM's optimizers are strong enough to figure out that "main"
should return true. However, this result is dependent on having
optimizations enabled!
N.B. This change also permits the usage of dllimport declarators inside
of template arguments; they are sufficiently constant for such a
purpose. Add tests to make sure we don't regress here.
llvm-svn: 211677
The address of dllimport functions can be accessed one of two ways:
- Through the IAT which is symbolically referred to with a symbol
starting with __imp_.
- Via the wrapper-function which ends up calling through the __imp_
symbol.
The problem with using the wrapper-function is that it's address will
not compare as equal in all translation units. Specifically, it will
compare unequally with the translation unit which defines the function.
This fixes PR19955.
llvm-svn: 211570
The address of dllimport variables isn't something that can be
meaningfully used in a constexpr context and isn't suitable for
evaluation at load-time. They require loads from memory to properly
evaluate.
This fixes PR19955.
Differential Revision: http://reviews.llvm.org/D4250
llvm-svn: 211568
expression of array-of-unknown-bound type, don't try to complete the array
bound, and return the alignment of the element type rather than 1.
llvm-svn: 210608
Summary:
Gracefully fail to evaluate a constant expression if its type is
unknown, rather than failing an assertion trying to access the type.
Reviewers: klimek
Reviewed By: klimek
CC: chandlerc, cfe-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D3075
llvm-svn: 203950
initialized from a constant expression in C++98, it can be used in
constant expressions, even if it was brace-initialized. Patch by
Rahul Jain!
llvm-svn: 200098
A return type is the declared or deduced part of the function type specified in
the declaration.
A result type is the (potentially adjusted) type of the value of an expression
that calls the function.
Rule of thumb:
* Declarations have return types and parameters.
* Expressions have result types and arguments.
llvm-svn: 200082