[PATCH] D25321: Fix PR13910: Don't warn that __builtin_unreachable() is unreachable

Alex L via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 6 08:19:13 PDT 2016


On 6 October 2016 at 15:50, David Blaikie <dblaikie at gmail.com> wrote:

>
>
> On Thu, Oct 6, 2016 at 6:16 AM Alex Lorenz <arphaman at gmail.com> wrote:
>
>> arphaman created this revision.
>> arphaman added reviewers: dblaikie, krememek.
>> arphaman added a subscriber: cfe-commits.
>> arphaman set the repository for this revision to rL LLVM.
>>
>> This patch fixes the issue of clang emitting an unreachable warning when
>> it encounters unreachable `__builtin_unreachable()` statements. It detects
>> references to `__builtin_unreachable` and doesn't emit an unreachable
>> warning for them.
>>
>>
>> Repository:
>>   rL LLVM
>>
>> https://reviews.llvm.org/D25321
>>
>> Files:
>>   lib/Analysis/ReachableCode.cpp
>>   test/Sema/warn-unreachable.c
>>
>>
>> Index: test/Sema/warn-unreachable.c
>> ===================================================================
>> --- test/Sema/warn-unreachable.c
>> +++ test/Sema/warn-unreachable.c
>> @@ -396,3 +396,40 @@
>>    else
>>      calledFun();
>>  }
>> +
>> +int pr13910_foo(int x) {
>> +  if (x == 1)
>> +    return 0;
>> +  else
>> +    return x;
>> +  __builtin_unreachable(); // expected no warning
>> +}
>> +
>> +int pr13910_bar(int x) {
>> +  switch (x) {
>> +  default:
>> +    return x + 1;
>> +  }
>> +  pr13910_foo(x); // expected-warning {{code will never be executed}}
>> +}
>> +
>> +int pr13910_bar2(int x) {
>> +  if (x == 1)
>> +    return 0;
>> +  else
>> +    return x;
>> +  pr13910_foo(x);          // expected-warning {{code will never be
>> executed}}
>> +  __builtin_unreachable(); // expected no warning
>> +  pr13910_foo(x);          // expected-warning {{code will never be
>> executed}}
>>
>
> Seems strange to have two warnings here ^ is that a separate bug?
>

It seems that it might be, yeah. For example, clang emits two unreachable
warnings for the two `foo` calls in this code:

int foo() {
  return 0;
}
int bar(int x) {
  if (x == 0)
    return x + 1;
  else
    return x;
  foo();
  return 0;
  foo();
}

But just one when the `return 0` that's between the two `foo` calls is
removed. It doesn't seem like there's a PR for this issue, I'll file one
later on today.



>
>
>> +}
>> +
>> +void pr13910_noreturn() {
>> +  raze();
>> +  __builtin_unreachable(); // expected no warning
>> +}
>> +
>> +void pr13910_assert() {
>> +  myassert(0 && "unreachable");
>> +  return;
>> +  __builtin_unreachable(); // expected no warning
>> +}
>> Index: lib/Analysis/ReachableCode.cpp
>> ===================================================================
>> --- lib/Analysis/ReachableCode.cpp
>> +++ lib/Analysis/ReachableCode.cpp
>> @@ -58,6 +58,15 @@
>>    return false;
>>  }
>>
>> +static bool isBuiltinUnreachable(const CFGBlock *B, const Stmt *S) {
>> +  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(S)) {
>> +    const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
>> +    return FDecl && FDecl->getIdentifier() &&
>> +           FDecl->getBuiltinID() == Builtin::BI__builtin_unreachable;
>> +  }
>> +  return false;
>> +}
>> +
>>  static bool isDeadReturn(const CFGBlock *B, const Stmt *S) {
>>    // Look to see if the current control flow ends with a 'return', and
>> see if
>>    // 'S' is a substatement. The 'return' may not be the last element in
>> the
>> @@ -574,8 +583,7 @@
>>
>>    if (isa<BreakStmt>(S)) {
>>      UK = reachable_code::UK_Break;
>> -  }
>> -  else if (isTrivialDoWhile(B, S)) {
>> +  } else if (isTrivialDoWhile(B, S) || isBuiltinUnreachable(B, S)) {
>>      return;
>>    }
>>    else if (isDeadReturn(B, S)) {
>>
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20161006/bc58d036/attachment.html>


More information about the cfe-commits mailing list