summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CGExprScalar.cpp
Commit message (Collapse)AuthorAgeFilesLines
* Port getLocStart -> getBeginLocStephen Kelly2018-08-091-6/+5
| | | | | | | | | | Reviewers: teemperor! Subscribers: jholewinski, whisperity, jfb, cfe-commits Differential Revision: https://reviews.llvm.org/D50350 llvm-svn: 339385
* Remove trailing spaceFangrui Song2018-07-301-1/+1
| | | | | | sed -Ei 's/[[:space:]]+$//' include/**/*.{def,h,td} lib/**/*.{cpp,h} llvm-svn: 338291
* [clang][ubsan] Implicit Conversion Sanitizer - integer truncation - clang partRoman Lebedev2018-07-301-16/+89
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: C and C++ are interesting languages. They are statically typed, but weakly. The implicit conversions are allowed. This is nice, allows to write code while balancing between getting drowned in everything being convertible, and nothing being convertible. As usual, this comes with a price: ``` unsigned char store = 0; bool consume(unsigned int val); void test(unsigned long val) { if (consume(val)) { // the 'val' is `unsigned long`, but `consume()` takes `unsigned int`. // If their bit widths are different on this platform, the implicit // truncation happens. And if that `unsigned long` had a value bigger // than UINT_MAX, then you may or may not have a bug. // Similarly, integer addition happens on `int`s, so `store` will // be promoted to an `int`, the sum calculated (0+768=768), // and the result demoted to `unsigned char`, and stored to `store`. // In this case, the `store` will still be 0. Again, not always intended. store = store + 768; // before addition, 'store' was promoted to int. } // But yes, sometimes this is intentional. // You can either make the conversion explicit (void)consume((unsigned int)val); // or mask the value so no bits will be *implicitly* lost. (void)consume((~((unsigned int)0)) & val); } ``` Yes, there is a `-Wconversion`` diagnostic group, but first, it is kinda noisy, since it warns on everything (unlike sanitizers, warning on an actual issues), and second, there are cases where it does **not** warn. So a Sanitizer is needed. I don't have any motivational numbers, but i know i had this kind of problem 10-20 times, and it was never easy to track down. The logic to detect whether an truncation has happened is pretty simple if you think about it - https://godbolt.org/g/NEzXbb - basically, just extend (using the new, not original!, signedness) the 'truncated' value back to it's original width, and equality-compare it with the original value. The most non-trivial thing here is the logic to detect whether this `ImplicitCastExpr` AST node is **actually** an implicit conversion, //or// part of an explicit cast. Because the explicit casts are modeled as an outer `ExplicitCastExpr` with some `ImplicitCastExpr`'s as **direct** children. https://godbolt.org/g/eE1GkJ Nowadays, we can just use the new `part_of_explicit_cast` flag, which is set on all the implicitly-added `ImplicitCastExpr`'s of an `ExplicitCastExpr`. So if that flag is **not** set, then it is an actual implicit conversion. As you may have noted, this isn't just named `-fsanitize=implicit-integer-truncation`. There are potentially some more implicit conversions to be warned about. Namely, implicit conversions that result in sign change; implicit conversion between different floating point types, or between fp and an integer, when again, that conversion is lossy. One thing i know isn't handled is bitfields. This is a clang part. The compiler-rt part is D48959. Fixes [[ https://bugs.llvm.org/show_bug.cgi?id=21530 | PR21530 ]], [[ https://bugs.llvm.org/show_bug.cgi?id=37552 | PR37552 ]], [[ https://bugs.llvm.org/show_bug.cgi?id=35409 | PR35409 ]]. Partially fixes [[ https://bugs.llvm.org/show_bug.cgi?id=9821 | PR9821 ]]. Fixes https://github.com/google/sanitizers/issues/940. (other than sign-changing implicit conversions) Reviewers: rjmccall, rsmith, samsonov, pcc, vsk, eugenis, efriedma, kcc, erichkeane Reviewed By: rsmith, vsk, erichkeane Subscribers: erichkeane, klimek, #sanitizers, aaron.ballman, RKSimon, dtzWill, filcab, danielaustin, ygribov, dvyukov, milianw, mclow.lists, cfe-commits, regehr Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D48958 llvm-svn: 338288
* [CodeGenCXX] Emit strip.invariant.group with -fstrict-vtable-pointersPiotr Padlewski2018-07-021-3/+57
| | | | | | | | | | | | | | | Summary: Emmiting new intrinsic that strips invariant.groups to make devirtulization sound, as described in RFC: Devirtualization v2. Reviewers: rjmccall, rsmith, amharc, kuhar Subscribers: llvm-commits, cfe-commits Differential Revision: https://reviews.llvm.org/D47299 Co-authored-by: Krzysztof Pszeniczny <krzysztof.pszeniczny@gmail.com> llvm-svn: 336137
* [DebugInfo] Inline for without DebugLocationAnastasis Grammenos2018-06-211-0/+6
| | | | | | | | | | | | | Summary: This test is a strip down version of a function inside the amalgamated sqlite source. When converted to IR clang produces a phi instruction without debug location. This patch fixes the above issue. Differential Revision: https://reviews.llvm.org/D47720 llvm-svn: 335255
* [Fixed Point Arithmetic] Fixed Point Precision Bits and Fixed Point LiteralsLeonard Chan2018-06-201-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | This diff includes the logic for setting the precision bits for each primary fixed point type in the target info and logic for initializing a fixed point literal. Fixed point literals are declared using the suffixes ``` hr: short _Fract uhr: unsigned short _Fract r: _Fract ur: unsigned _Fract lr: long _Fract ulr: unsigned long _Fract hk: short _Accum uhk: unsigned short _Accum k: _Accum uk: unsigned _Accum ``` Errors are also thrown for illegal literal values ``` unsigned short _Accum u_short_accum = 256.0uhk; // expected-error{{the integral part of this literal is too large for this unsigned _Accum type}} ``` Differential Revision: https://reviews.llvm.org/D46915 llvm-svn: 335148
* Remove \brief commands from doxygen comments.Adrian Prantl2018-05-091-1/+1
| | | | | | | | | | | | | | | | | | | This is similar to the LLVM change https://reviews.llvm.org/D46290. We've been running doxygen with the autobrief option for a couple of years now. This makes the \brief markers into our comments redundant. Since they are a visual distraction and we don't want to encourage more \brief markers in new code either, this patch removes them all. Patch produced by for i in $(git grep -l '\@brief'); do perl -pi -e 's/\@brief //g' $i & done for i in $(git grep -l '\\brief'); do perl -pi -e 's/\\brief //g' $i & done Differential Revision: https://reviews.llvm.org/D46320 llvm-svn: 331834
* Clean carriage returns from lib/ and include/. NFC.Malcolm Parsons2018-04-161-23/+23
| | | | | | | | | | | | | | | | | | | | | | | | Summary: Clean carriage returns from lib/ and include/. NFC. (I have to make this change locally in order for `git diff` to show sane output after I edit a file, so I might as well ask for it to be committed. I don't have commit privs myself.) (Without this patch, `git rebase`ing any change involving SemaDeclCXX.cpp is a real nightmare. :( So while I have no right to ask for this to be committed, geez would it make my workflow easier if it were.) Here's the command I used to reformat things. (Requires bash and OSX/FreeBSD sed.) git grep -l $'\r' lib include | xargs sed -i -e $'s/\r//' find lib include -name '*-e' -delete Reviewers: malcolm.parsons Reviewed By: malcolm.parsons Subscribers: emaste, krytarowski, cfe-commits Differential Revision: https://reviews.llvm.org/D45591 Patch by Arthur O'Dwyer. llvm-svn: 330112
* [CodeGen] Ignore OpaqueValueExprs that are unique references to theirAkira Hatanaka2018-03-201-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | source expressions when iterating over a PseudoObjectExpr's semantic subexpression list. Previously the loop in emitPseudoObjectExpr would emit the IR for each OpaqueValueExpr that was in a PseudoObjectExpr's semantic-form expression list and use the result when the OpaqueValueExpr later appeared in other expressions. This caused an assertion failure when AggExprEmitter tried to copy the result of an OpaqueValueExpr and the copied type didn't have trivial copy/move constructors or assignment operators. This patch adds flag IsUnique to OpaqueValueExpr which indicates it is a unique reference to its source expression (it is not used in multiple places). The loop in emitPseudoObjectExpr ignores OpaqueValueExprs that are unique and CodeGen visitors simply traverse the source expressions of such OpaqueValueExprs. rdar://problem/34363596 Differential Revision: https://reviews.llvm.org/D39562 llvm-svn: 327939
* Recommit rL323952: [DebugInfo] Enable debug information for C99 VLA types.Sander de Smalen2018-02-031-13/+9
| | | | | | Fixed build issue when building with g++-4.8 (specialization after instantiation). llvm-svn: 324173
* Reverting patch rL323952 due to build errors that ISander de Smalen2018-02-011-9/+13
| | | | | | haven't encountered in local builds. llvm-svn: 323956
* [DebugInfo] Enable debug information for C99 VLA typesSander de Smalen2018-02-011-13/+9
| | | | | | | | | | | | | | | | | | | | | Summary: This patch enables debugging of C99 VLA types by generating more precise LLVM Debug metadata, using the extended DISubrange 'count' field that takes a DIVariable. This should implement: Bug 30553: Debug info generated for arrays is not what GDB expects (not as good as GCC's) https://bugs.llvm.org/show_bug.cgi?id=30553 Reviewers: echristo, aprantl, dexonsmith, clayborg, pcc, kristof.beyls, dblaikie Reviewed By: aprantl Subscribers: jholewinski, schweitz, davide, fhahn, JDevlieghere, cfe-commits Differential Revision: https://reviews.llvm.org/D41698 llvm-svn: 323952
* Track in the AST whether the operand to a UnaryOperator can overflow and ↵Aaron Ballman2018-01-091-25/+23
| | | | | | then use that logic when evaluating constant expressions and emitting codegen. llvm-svn: 322074
* [c++20] P0515R3: Parsing support and basic AST construction for operator <=>.Richard Smith2017-12-141-0/+1
| | | | | | | | | | | | | | | Adding the new enumerator forced a bunch more changes into this patch than I would have liked. The -Wtautological-compare warning was extended to properly check the new comparison operator, clang-format needed updating because it uses precedence levels as weights for determining where to break lines (and several operators increased their precedence levels with this change), thread-safety analysis needed changes to build its own IL properly for the new operator. All "real" semantic checking for this operator has been deferred to a future patch. For now, we use the relational comparison rules and arbitrarily give the builtin form of the operator a return type of 'void'. llvm-svn: 320707
* [CodeGen][X86] Fix handling of __fp16 vectors.Akira Hatanaka2017-12-091-6/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit fixes a bug in IRGen where it generates completely broken code for __fp16 vectors on X86. For example when the following code is compiled: half4 hv0, hv1, hv2; // these are vectors of __fp16. void foo221() { hv0 = hv1 + hv2; } clang generates the following IR, in which two i16 vectors are added: @hv1 = common global <4 x i16> zeroinitializer, align 8 @hv2 = common global <4 x i16> zeroinitializer, align 8 @hv0 = common global <4 x i16> zeroinitializer, align 8 define void @foo221() { %0 = load <4 x i16>, <4 x i16>* @hv1, align 8 %1 = load <4 x i16>, <4 x i16>* @hv2, align 8 %add = add <4 x i16> %0, %1 store <4 x i16> %add, <4 x i16>* @hv0, align 8 ret void } To fix the bug, this commit uses the code committed in r314056, which modified clang to promote and truncate __fp16 vectors to and from float vectors in the AST. It also fixes another IRGen bug where a short value is assigned to an __fp16 variable without any integer-to-floating-point conversion, as shown in the following example: __fp16 a; short b; void foo1() { a = b; } @b = common global i16 0, align 2 @a = common global i16 0, align 2 define void @foo1() #0 { %0 = load i16, i16* @b, align 2 store i16 %0, i16* @a, align 2 ret void } rdar://problem/20625184 Differential Revision: https://reviews.llvm.org/D40112 llvm-svn: 320215
* [CGExprScalar] Add missing types in function GetIntrinsicGuozhi Wei2017-10-191-2/+11
| | | | | | | | In function GetIntrinsic, not all types are covered. Types double and long long are missed, type long is wrongly treated same as int, it should be same as long long. These problems cause compiler crashes when compiling code in PR31161. This patch fixed the problem. Differential Revision: https://reviews.llvm.org/D38820 llvm-svn: 316179
* [CGExprScalar] In EmitCompare trunc the result if it has different type as ↵Guozhi Wei2017-10-101-0/+10
| | | | | | | | | | | | | | | | E->getType() Usually compare expression should return i1 type, so EmitScalarConversion is called before return return EmitScalarConversion(Result, CGF.getContext().BoolTy, E->getType(), E->getExprLoc()); But when ppc intrinsic is called to compare vectors, the ppc intrinsic can return i32 even E->getType() is BoolTy, in this case EmitScalarConversion does nothing, an i32 type result is returned and causes crash later. This patch detects this case and truncates the result before return. Differential Revision: https://reviews.llvm.org/D38656 llvm-svn: 315358
* Silence unused variable warning in Release builds.Benjamin Kramer2017-09-231-0/+1
| | | | llvm-svn: 314066
* Promote storage-only __fp16 vector operands to float vectors.Akira Hatanaka2017-09-231-4/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit fixes a bug in the handling of storage-only __fp16 vectors where clang didn't promote __fp16 vector operands to float vectors. Conceptually, it performs the following transformation on the AST in CreateBuiltinBinOp and CreateBuiltinUnaryOp: (Before) typedef __fp16 half4 __attribute__ ((vector_size (8))); typedef float float4 __attribute__ ((vector_size (16))); half4 hv0, hv1, hv2, hv3; hv0 = hv1 + hv2 + hv3; (After) float4 t0 = (float4)hv1 + (float4)hv2; float4 t1 = t0 + (float4)hv3; hv0 = (half4)t1; Note that this commit fixes the bug for targets that set HalfArgsAndReturns to true (ARM and ARM64). Targets using intrinsics such as llvm.convert.to.fp16 to handle __fp16 are still broken. rdar://problem/20625184 Differential Revision: https://reviews.llvm.org/D32520 llvm-svn: 314056
* Teach clang to tolerate the 'p = nullptr + n' idiom used by glibcAndrew Kaylor2017-09-191-0/+24
| | | | | | Differential Revision: https://reviews.llvm.org/D37042 llvm-svn: 313666
* Recommit "Add _Float16 as a C/C++ source language type"Sjoerd Meijer2017-09-081-1/+1
| | | | | | | | This is a recommit of r312781; in some build configurations variable names are omitted, so changed the new regression test accordingly. llvm-svn: 312794
* Revert "Add _Float16 as a C/C++ source language type"Sjoerd Meijer2017-09-081-1/+1
| | | | | | | The clang-with-lto-ubuntu bot didn't like the new regression test, revert while I investigate the issue. llvm-svn: 312784
* Add _Float16 as a C/C++ source language typeSjoerd Meijer2017-09-081-1/+1
| | | | | | | | | | | This adds _Float16 as a source language type, which is a 16-bit floating point type defined in C11 extension ISO/IEC TS 18661-3. In follow up patches documentation and more tests will be added. Differential Revision: https://reviews.llvm.org/D33719 llvm-svn: 312781
* [IRGen] Evaluate constant static variables referenced through memberAlex Lorenz2017-08-251-13/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | expressions C++ allows us to reference static variables through member expressions. Prior to this commit, non-integer static variables that were referenced using a member expression were always emitted using lvalue loads. The old behaviour introduced an inconsistency between regular uses of static variables and member expressions uses. For example, the following program compiled and linked successfully: struct Foo { constexpr static const char *name = "foo"; }; int main() { return Foo::name[0] == 'f'; } but this program failed to link because "Foo::name" wasn't found: struct Foo { constexpr static const char *name = "foo"; }; int main() { Foo f; return f.name[0] == 'f'; } This commit ensures that constant static variables referenced through member expressions are emitted in the same way as ordinary static variable references. rdar://33942261 Differential Revision: https://reviews.llvm.org/D36876 llvm-svn: 311772
* [ubsan] Teach the pointer overflow check that "p - <unsigned> <= p" (PR33430)Vedant Kumar2017-07-131-15/+23
| | | | | | | | | | | | | | | | | | | | | The pointer overflow check gives false negatives when dealing with expressions in which an unsigned value is subtracted from a pointer. This is summarized in PR33430 [1]: ubsan permits the result of the subtraction to be greater than "p", but it should not. To fix the issue, we should track whether or not the pointer expression is a subtraction. If it is, and the indices are unsigned, we know to expect "p - <unsigned> <= p". I've tested this by running check-{llvm,clang} with a stage2 ubsan-enabled build. I've also added some tests to compiler-rt, which are in D34122. [1] https://bugs.llvm.org/show_bug.cgi?id=33430 Differential Revision: https://reviews.llvm.org/D34121 llvm-svn: 307955
* [ubsan] Detect invalid unsigned pointer index expression (clang)Vedant Kumar2017-06-121-20/+31
| | | | | | | | | | | | | | | | | | | | | | | | Adding an unsigned offset to a base pointer has undefined behavior if the result of the expression would precede the base. An example from @regehr: int foo(char *p, unsigned offset) { return p + offset >= p; // This may be optimized to '1'. } foo(p, -1); // UB. This patch extends the pointer overflow check in ubsan to detect invalid unsigned pointer index expressions. It changes the instrumentation to only permit non-negative offsets in pointer index expressions when all of the GEP indices are unsigned. Testing: check-llvm, check-clang run on a stage2, ubsan-instrumented build. Differential Revision: https://reviews.llvm.org/D33910 llvm-svn: 305216
* [CodeGen] Surround assertion with parentheses.Davide Italiano2017-06-011-1/+1
| | | | | | This should placate GCC's -Wparentheses. llvm-svn: 304499
* [ubsan] Add a check for pointer overflow UBVedant Kumar2017-06-011-34/+176
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Check pointer arithmetic for overflow. For some more background on this check, see: https://wdtz.org/catching-pointer-overflow-bugs.html https://reviews.llvm.org/D20322 Patch by Will Dietz and John Regehr! This version of the patch is different from the original in a few ways: - It introduces the EmitCheckedInBoundsGEP utility which inserts checks when the pointer overflow check is enabled. - It does some constant-folding to reduce instrumentation overhead. - It does not check some GEPs in CGExprCXX. I'm not sure that inserting checks here, or in CGClass, would catch many bugs. Possible future directions for this check: - Introduce CGF.EmitCheckedStructGEP, to detect overflows when accessing structures. Testing: Apart from the added lit test, I ran check-llvm and check-clang with a stage2, ubsan-instrumented clang. Will and John have also done extensive testing on numerous open source projects. Differential Revision: https://reviews.llvm.org/D33305 llvm-svn: 304459
* CodeGen: Cast alloca to expected address spaceYaxun Liu2017-05-181-4/+3
| | | | | | | | | | | Alloca always returns a pointer in alloca address space, which may be different from the type defined by the language. For example, in C++ the auto variables are in the default address space. Therefore cast alloca to the expected address space when necessary. Differential Revision: https://reviews.llvm.org/D32248 llvm-svn: 303370
* [ubsan] Mark overflow checks with !nosanitizeVedant Kumar2017-05-091-1/+1
| | | | | | | | | Sanitizer instrumentation generally needs to be marked with !nosanitize, but we're not doing this properly for ubsan's overflow checks. r213291 has more information about why this is needed. llvm-svn: 302598
* Rename a method. NFC.Vedant Kumar2017-05-091-3/+3
| | | | llvm-svn: 302490
* [ubsan] Skip overflow checks on safe arithmetic (fixes PR32874)Vedant Kumar2017-05-021-8/+78
| | | | | | | | | | | | | | | | | | | | | | | | Currently, ubsan emits overflow checks for arithmetic that is known to be safe at compile-time, e.g: 1 + 1 => CheckedAdd(1, 1) This leads to breakage when using the __builtin_prefetch intrinsic. LLVM expects the arguments to @llvm.prefetch to be constant integers, and when ubsan inserts unnecessary checks on the operands to the intrinsic, this contract is broken, leading to verifier failures (see PR32874). Instead of special-casing __builtin_prefetch for ubsan, this patch fixes the underlying problem, i.e that clang currently emits unnecessary overflow checks. Testing: I ran the check-clang and check-ubsan targets with a stage2, ubsan-enabled build of clang. I added a regression test for PR32874, and some extra checking to make sure we don't regress runtime checking for unsafe arithmetic. The existing ubsan-promoted-arithmetic.cpp test also provides coverage for this change. llvm-svn: 301988
* Set FMF for -ffp-contract=fastAdam Nemet2017-04-041-4/+24
| | | | | | | | | | | | | | With this, FMF(contract) becomes an alternative way to express the request to contract. These are currently only propagated for FMul, FAdd and FSub. The rest will be added as more FMFs are hooked up for this. This is toward fixing PR25721. Differential Revision: https://reviews.llvm.org/D31168 llvm-svn: 299469
* Preserve vec3 type.Jin-Gu Kang2017-04-041-5/+12
| | | | | | | | | | | | | | Summary: Preserve vec3 type with CodeGen option. Reviewers: Anastasia, bruno Reviewed By: Anastasia Subscribers: bruno, ahatanak, cfe-commits Differential Revision: https://reviews.llvm.org/D30810 llvm-svn: 299445
* Use FPContractModeKind universallyAdam Nemet2017-03-291-6/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | FPContractModeKind is the codegen option flag which is already ternary (off, on, fast). This makes it universally the type for the contractable info across the front-end: * In FPOptions (i.e. in the Sema + in the expression nodes). * In LangOpts::DefaultFPContractMode which is the option that initializes FPOptions in the Sema. Another way to look at this change is that before fp-contractable on/off were the only states handled to the front-end: * For "on", FMA folding was performed by the front-end * For "fast", we simply forwarded the flag to TargetOptions to handle it in LLVM Now off/on/fast are all exposed because for fast we will generate fast-math-flags during CodeGen. This is toward moving fp-contraction=fast from an LLVM TargetOption to a FastMathFlag in order to fix PR25721. --- This is a recommit of r299027 with an adjustment to the test CodeGenCUDA/fp-contract.cu. The test assumed that even though -ffp-contract=on is passed FE-based folding of FMA won't happen. This is obviously wrong since the user is asking for this explicitly with the option. CUDA is different that -ffp-contract=fast is on by default. The test used to "work" because contract=fast and contract=on were maintained separately and we didn't fold in the FE because contract=fast was on due to the target-default. This patch consolidates the contract=on/fast/off state into a ternary state hence the change in behavior. --- Differential Revision: https://reviews.llvm.org/D31167 llvm-svn: 299033
* Revert "Use FPContractModeKind universally"Adam Nemet2017-03-291-1/+6
| | | | | | | | This reverts commit r299027. It's causing a test failure in clang's CodeGenCUDE/fp-contract.cu llvm-svn: 299029
* Use FPContractModeKind universallyAdam Nemet2017-03-291-6/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | FPContractModeKind is the codegen option flag which is already ternary (off, on, fast). This makes it universally the type for the contractable info across the front-end: * In FPOptions (i.e. in the Sema + in the expression nodes). * In LangOpts::DefaultFPContractMode which is the option that initializes FPOptions in the Sema. Another way to look at this change is that before fp-contractable on/off were the only states handled to the front-end: * For "on", FMA folding was performed by the front-end * For "fast", we simply forwarded the flag to TargetOptions to handle it in LLVM Now off/on/fast are all exposed because for fast we will generate fast-math-flags during CodeGen. This is toward moving fp-contraction=fast from an LLVM TargetOption to a FastMathFlag in order to fix PR25721. Differential Revision: https://reviews.llvm.org/D31167 llvm-svn: 299027
* Encapsulate FPOptions and use it consistentlyAdam Nemet2017-03-271-6/+6
| | | | | | | | | | | | | | | | | | Sema holds the current FPOptions which is adjusted by 'pragma STDC FP_CONTRACT'. This then gets propagated into expression nodes as they are built. This encapsulates FPOptions so that this propagation happens opaquely rather than directly with the fp_contractable on/off bit. This allows controlled transitioning of fp_contractable to a ternary value (off, on, fast). It will also allow adding more fast-math flags later. This is toward moving fp-contraction=fast from an LLVM TargetOption to a FastMathFlag in order to fix PR25721. Differential Revision: https://reviews.llvm.org/D31166 llvm-svn: 298877
* [coroutines] Add codegen for await and yield expressionsGor Nishanov2017-03-261-0/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Details: Emit suspend expression which roughly looks like: auto && x = CommonExpr(); if (!x.await_ready()) { llvm_coro_save(); x.await_suspend(...); (*) llvm_coro_suspend(); (**) } x.await_resume(); where the result of the entire expression is the result of x.await_resume() (*) If x.await_suspend return type is bool, it allows to veto a suspend: if (x.await_suspend(...)) llvm_coro_suspend(); (**) llvm_coro_suspend() encodes three possible continuations as a switch instruction: %where-to = call i8 @llvm.coro.suspend(...) switch i8 %where-to, label %coro.ret [ ; jump to epilogue to suspend i8 0, label %yield.ready ; go here when resumed i8 1, label %yield.cleanup ; go here when destroyed ] llvm-svn: 298784
* [ubsan] Add a nullability sanitizerVedant Kumar2017-03-141-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Teach UBSan to detect when a value with the _Nonnull type annotation assumes a null value. Call expressions, initializers, assignments, and return statements are all checked. Because _Nonnull does not affect IRGen, the new checks are disabled by default. The new driver flags are: -fsanitize=nullability-arg (_Nonnull violation in call) -fsanitize=nullability-assign (_Nonnull violation in assignment) -fsanitize=nullability-return (_Nonnull violation in return stmt) -fsanitize=nullability (all of the above) This patch builds on top of UBSan's existing support for detecting violations of the nonnull attributes ('nonnull' and 'returns_nonnull'), and relies on the compiler-rt support for those checks. Eventually we will need to update the diagnostic messages in compiler-rt (there are FIXME's for this, which will be addressed in a follow-up). One point of note is that the nullability-return check is only allowed to kick in if all arguments to the function satisfy their nullability preconditions. This makes it necessary to emit some null checks in the function body itself. Testing: check-clang and check-ubsan. I also built some Apple ObjC frameworks with an asserts-enabled compiler, and verified that we get valid reports. Differential Revision: https://reviews.llvm.org/D30762 llvm-svn: 297700
* Don't assume cleanup emission preserves dominance in expr evaluationReid Kleckner2017-03-061-5/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Because of the existence branches out of GNU statement expressions, it is possible that emitting cleanups for a full expression may cause the new insertion point to not be dominated by the result of the inner expression. Consider this example: struct Foo { Foo(); ~Foo(); int x; }; int g(Foo, int); int f(bool cond) { int n = g(Foo(), ({ if (cond) return 0; 42; })); return n; } Before this change, result of the call to 'g' did not dominate its use in the store to 'n'. The early return exit from the statement expression branches to a shared cleanup block, which ends in a switch between the fallthrough destination (the assignment to 'n') or the function exit block. This change solves the problem by spilling and reloading expression evaluation results when any of the active cleanups have branches. I audited the other call sites of enterFullExpression, and they don't appear to keep and Values live across the site of the cleanup, except in ARC code. I wasn't able to create a test case for ARC that exhibits this problem, though. Reviewers: rjmccall, rsmith Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D30590 llvm-svn: 297084
* Fix -Wparentheses warningVedant Kumar2017-02-251-2/+2
| | | | llvm-svn: 296246
* Retry: [profiling] Fix profile counter increment when emitting selects (PR32019)Vedant Kumar2017-02-251-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | 2nd attempt: the first was in r296231, but it had a use after lifetime bug. Clang has logic to lower certain conditional expressions directly into llvm select instructions. However, it does not emit the correct profile counter increment as it does this: it emits an unconditional increment of the counter for the 'then branch', even if the value selected is from the 'else branch' (this is PR32019). That means, given the following snippet, we would report that "0" is selected twice, and that "1" is never selected: int f1(int x) { return x ? 0 : 1; ^2 ^0 } f1(0); f1(1); Fix the problem by using the instrprof_increment_step intrinsic to do the proper increment. llvm-svn: 296245
* Revert "[profiling] Fix profile counter increment when emitting selects ↵Vedant Kumar2017-02-251-4/+2
| | | | | | | | | | | | | | | | | | | | | (PR32019)" This reverts commit r296231. It causes an assertion failure on 32-bit machines clang: /export/users/atombot/llvm/clang-atom-d525-fedora-rel/llvm/lib/IR/Instructions.cpp:263: void llvm::CallInst::init(llvm::FunctionType*, llvm::Value*, llvm::ArrayRef<llvm::Value*>, llvm::ArrayRef<llvm::OperandBundleDefT<llvm::Value*> >, const llvm::Twine&): Assertion `(i >= FTy->getNumParams() || FTy->getParamType(i) == Args[i]->getType()) && "Calling a function with a bad signature!"' failed. llvm::sys::PrintStackTrace(llvm::raw_ostream&) (/export/users/atombot/llvm/clang-atom-d525-fedora-rel/stage1/./bin/clang+0x1c5fbfa) llvm::sys::RunSignalHandlers() (/export/users/atombot/llvm/clang-atom-d525-fedora-rel/stage1/./bin/clang+0x1c5dc7e) SignalHandler(int) (/export/users/atombot/llvm/clang-atom-d525-fedora-rel/stage1/./bin/clang+0x1c5dde2) __restore_rt (/lib64/libpthread.so.0+0x3f1d00efa0) __GI_raise /home/glibctest/rpmbuild/BUILD/glibc-2.17-c758a686/signal/../nptl/sysdeps/unix/sysv/linux/raise.c:56:0 __GI_abort /home/glibctest/rpmbuild/BUILD/glibc-2.17-c758a686/stdlib/abort.c:92:0 __assert_fail_base /home/glibctest/rpmbuild/BUILD/glibc-2.17-c758a686/assert/assert.c:92:0 (/lib64/libc.so.6+0x3f1c82e622) llvm::CallInst::init(llvm::FunctionType*, llvm::Value*, llvm::ArrayRef<llvm::Value*>, llvm::ArrayRef<llvm::OperandBundleDefT<llvm::Value*> >, llvm::Twine const&) (/export/users/atombot/llvm/clang-atom-d525-fedora-rel/stage1/./bin/clang+0x1804e3a) clang::CodeGen::CodeGenPGO::emitCounterIncrement(clang::CodeGen::CGBuilderTy&, clang::Stmt const*, llvm::Value*) (/export/users/atombot/llvm/clang-atom-d525-fedora-rel/stage1/./bin/clang+0x1ec7891) llvm-svn: 296234
* [profiling] Fix profile counter increment when emitting selects (PR32019)Vedant Kumar2017-02-251-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | Clang has logic to lower certain conditional expressions directly into llvm select instructions. However, it does not emit the correct profile counter increment as it does this: it emits an unconditional increment of the counter for the 'then branch', even if the value selected is from the 'else branch' (this is PR32019). That means, given the following snippet, we would report that "0" is selected twice, and that "1" is never selected: int f1(int x) { return x ? 0 : 1; ^2 ^0 } f1(0); f1(1); Fix the problem by using the instrprof_increment_step intrinsic to do the proper increment. llvm-svn: 296231
* [ubsan] Detect signed overflow UB in remainder operationsVedant Kumar2017-02-251-4/+4
| | | | | | | | | Teach ubsan to diagnose remainder operations which have undefined behavior due to signed overflow (e.g INT_MIN % -1). Differential Revision: https://reviews.llvm.org/D29437 llvm-svn: 296214
* [ubsan] Omit superflous overflow checks for promoted arithmetic (PR20193)Vedant Kumar2017-02-251-4/+71
| | | | | | | | | | | | | | | | C requires the operands of arithmetic expressions to be promoted if their types are smaller than an int. Ubsan emits overflow checks when this sort of type promotion occurs, even if there is no way to actually get an overflow with the promoted type. This patch teaches clang how to omit the superflous overflow checks (addressing PR20193). Testing: check-clang and check-ubsan. Differential Revision: https://reviews.llvm.org/D29369 llvm-svn: 296213
* [ObjC][CodeGen] CodeGen support for @available.Erik Pilkington2017-02-231-0/+18
| | | | | | | | | | | | CodeGens uses of @available into calls to the compiler-rt function __isOSVersionAtLeast. This commit is part of a feature that I proposed here: http://lists.llvm.org/pipermail/cfe-dev/2016-July/049851.html Differential revision: https://reviews.llvm.org/D27827 llvm-svn: 296015
* Re-apply "[ubsan] Sanity-check shift amounts before truncation"Vedant Kumar2017-01-301-7/+9
| | | | | | | | | | | | | | | | | | | This re-applies r293343 (reverts commit r293475) with a fix for an assertion failure caused by a missing integer cast. I tested this patch by using the built compiler to compile X86FastISel.cpp.o with ubsan. Original commit message: Ubsan does not report UB shifts in some cases where the shift exponent needs to be truncated to match the type of the shift base. We perform a range check on the truncated shift amount, leading to false negatives. Fix the issue (PR27271) by performing the range check on the original shift amount. Differential Revision: https://reviews.llvm.org/D29234 llvm-svn: 293572
* Revert "r293343 - [ubsan] Sanity-check shift amounts before truncationAlex Lorenz2017-01-301-2/+2
| | | | | | | | | | | (fixes PR27271)" After r293343 clang fails to compile itself with -fsanitize=undefined ( http://lab.llvm.org:8080/green/job/clang-stage2-cmake-RgSan_build/). rdar://30259929 llvm-svn: 293475
OpenPOWER on IntegriCloud