1 //===- unittests/StaticAnalyzer/TestReturnValueUnderConstruction.cpp ------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "CheckerRegistration.h"
10 #include "clang/StaticAnalyzer/Core/Checker.h"
11 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
12 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
13 #include "clang/StaticAnalyzer/Frontend/AnalysisConsumer.h"
14 #include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
15 #include "clang/Tooling/Tooling.h"
16 #include "gtest/gtest.h"
23 class TestReturnValueUnderConstructionChecker
24 : public Checker
<check::PostCall
> {
26 void checkPostCall(const CallEvent
&Call
, CheckerContext
&C
) const {
27 // Only calls with origin expression are checked. These are `returnC()`,
28 // `returnD()`, C::C() and D::D().
29 if (!Call
.getOriginExpr())
32 // Since `returnC` returns an object by value, the invocation results
33 // in an object of type `C` constructed into variable `c`. Thus the
34 // return value of `CallEvent::getReturnValueUnderConstruction()` must
35 // be non-empty and has to be a `MemRegion`.
36 std::optional
<SVal
> RetVal
= Call
.getReturnValueUnderConstruction();
38 ASSERT_TRUE(RetVal
->getAsRegion());
40 const auto *RetReg
= cast
<TypedValueRegion
>(RetVal
->getAsRegion());
41 const Expr
*OrigExpr
= Call
.getOriginExpr();
42 ASSERT_EQ(OrigExpr
->getType()->getCanonicalTypeInternal(),
43 RetReg
->getValueType()->getCanonicalTypeInternal());
47 void addTestReturnValueUnderConstructionChecker(
48 AnalysisASTConsumer
&AnalysisConsumer
, AnalyzerOptions
&AnOpts
) {
49 AnOpts
.CheckersAndPackages
=
50 {{"test.TestReturnValueUnderConstruction", true}};
51 AnalysisConsumer
.AddCheckerRegistrationFn([](CheckerRegistry
&Registry
) {
52 Registry
.addChecker
<TestReturnValueUnderConstructionChecker
>(
53 "test.TestReturnValueUnderConstruction", "", "");
57 TEST(TestReturnValueUnderConstructionChecker
,
58 ReturnValueUnderConstructionChecker
) {
59 EXPECT_TRUE(runCheckerOnCode
<addTestReturnValueUnderConstructionChecker
>(
77 EXPECT_TRUE(runCheckerOnCode
<addTestReturnValueUnderConstructionChecker
>(
96 EXPECT_TRUE(runCheckerOnCode
<addTestReturnValueUnderConstructionChecker
>(