diff options
Diffstat (limited to 'test/SemaCXX/return-noreturn.cpp')
-rw-r--r-- | test/SemaCXX/return-noreturn.cpp | 100 |
1 files changed, 97 insertions, 3 deletions
diff --git a/test/SemaCXX/return-noreturn.cpp b/test/SemaCXX/return-noreturn.cpp index 531dc23..cdd96e6 100644 --- a/test/SemaCXX/return-noreturn.cpp +++ b/test/SemaCXX/return-noreturn.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 %s -fsyntax-only -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code -Wno-covered-switch-default -// RUN: %clang_cc1 %s -fsyntax-only -std=c++11 -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code -Wno-covered-switch-default +// RUN: %clang_cc1 %s -fsyntax-only -fcxx-exceptions -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code -Wno-covered-switch-default +// RUN: %clang_cc1 %s -fsyntax-only -fcxx-exceptions -std=c++11 -verify -Wreturn-type -Wmissing-noreturn -Wno-unreachable-code -Wno-covered-switch-default // A destructor may be marked noreturn and should still influence the CFG. void pr6884_abort() __attribute__((noreturn)); @@ -143,7 +143,84 @@ template <PR9412_MatchType type> int PR9412_t() { } // expected-warning {{control reaches end of non-void function}} void PR9412_f() { - PR9412_t<PR9412_Exact>(); // expected-note {{in instantiation of function template specialization 'PR9412_t<0>' requested here}} + PR9412_t<PR9412_Exact>(); // expected-note {{in instantiation of function template specialization 'PR9412_t<PR9412_MatchType::PR9412_Exact>' requested here}} +} + +struct NoReturn { + ~NoReturn() __attribute__((noreturn)); + operator bool() const; +}; +struct Return { + ~Return(); + operator bool() const; +}; + +int testTernaryUnconditionalNoreturn() { + true ? NoReturn() : NoReturn(); +} + +int testTernaryStaticallyConditionalNoretrunOnTrue() { + true ? NoReturn() : Return(); +} + +int testTernaryStaticallyConditionalRetrunOnTrue() { + true ? Return() : NoReturn(); +} // expected-warning {{control reaches end of non-void function}} + +int testTernaryStaticallyConditionalNoretrunOnFalse() { + false ? Return() : NoReturn(); +} + +int testTernaryStaticallyConditionalRetrunOnFalse() { + false ? NoReturn() : Return(); +} // expected-warning {{control reaches end of non-void function}} + +int testTernaryConditionalNoreturnTrueBranch(bool value) { + value ? (NoReturn() || NoReturn()) : Return(); +} // expected-warning {{control may reach end of non-void function}} + +int testTernaryConditionalNoreturnFalseBranch(bool value) { + value ? Return() : (NoReturn() || NoReturn()); +} // expected-warning {{control may reach end of non-void function}} + +int testConditionallyExecutedComplexTernaryTrueBranch(bool value) { + value || (true ? NoReturn() : true); +} // expected-warning {{control may reach end of non-void function}} + +int testConditionallyExecutedComplexTernaryFalseBranch(bool value) { + value || (false ? true : NoReturn()); +} // expected-warning {{control may reach end of non-void function}} + +int testStaticallyExecutedLogicalOrBranch() { + false || NoReturn(); +} + +int testStaticallyExecutedLogicalAndBranch() { + true && NoReturn(); +} + +int testStaticallySkippedLogicalOrBranch() { + true || NoReturn(); +} // expected-warning {{control reaches end of non-void function}} + +int testStaticallySkppedLogicalAndBranch() { + false && NoReturn(); +} // expected-warning {{control reaches end of non-void function}} + +int testConditionallyExecutedComplexLogicalBranch(bool value) { + value || (true && NoReturn()); +} // expected-warning {{control may reach end of non-void function}} + +int testConditionallyExecutedComplexLogicalBranch2(bool value) { + (true && value) || (true && NoReturn()); +} // expected-warning {{control may reach end of non-void function}} + +int testConditionallyExecutedComplexLogicalBranch3(bool value) { + (false && (Return() || true)) || (true && NoReturn()); +} + +int testConditionallyExecutedComplexLogicalBranch4(bool value) { + false || ((Return() || true) && (true && NoReturn())); } #if __cplusplus >= 201103L @@ -168,3 +245,20 @@ namespace LambdaVsTemporaryDtor { } // ok, initialization of lambda does not return } #endif + +// Ensure that function-try-blocks also check for return values properly. +int functionTryBlock1(int s) try { + return 0; +} catch (...) { +} // expected-warning {{control may reach end of non-void function}} + +int functionTryBlock2(int s) try { +} catch (...) { + return 0; +} // expected-warning {{control may reach end of non-void function}} + +int functionTryBlock3(int s) try { + return 0; +} catch (...) { + return 0; +} // ok, both paths return. |