Skip to content

Commit

Permalink
Merge pull request #444 from andreasfertig/fixIssue405
Browse files Browse the repository at this point in the history
Fixed #405: Show implicit casts in compound assignment operations.
  • Loading branch information
andreasfertig committed Feb 5, 2022
2 parents 604477f + de2ca8b commit 511bb4e
Show file tree
Hide file tree
Showing 18 changed files with 193 additions and 25 deletions.
42 changes: 42 additions & 0 deletions CodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "InsightsStrCat.h"
#include "NumberIterator.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Sema/Sema.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Path.h"
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -713,6 +714,47 @@ void CodeGenerator::InsertArg(const BinaryOperator* stmt)
}
//-----------------------------------------------------------------------------

void CodeGenerator::InsertArg(const CompoundAssignOperator* stmt)
{
LAMBDA_SCOPE_HELPER(BinaryOperator);

const bool needLHSParens{isa<BinaryOperator>(stmt->getLHS()->IgnoreImpCasts())};
WrapInParensIfNeeded(needLHSParens, [&] { InsertArg(stmt->getLHS()); });

mOutputFormatHelper.Append(" = ");

// we may need a cast around this back to the src type
const bool needCast{stmt->getLHS()->getType() != stmt->getComputationLHSType()};
if(needCast) {
mOutputFormatHelper.Append(kwStaticCast, "<", GetName(stmt->getLHS()->getType()), ">(");
}

WrapInParensIfNeeded(needLHSParens, [&] {
clang::ExprResult res = stmt->getLHS();

// This cast is not present in the AST. However, if the LHS type is smaller than RHS there is an implicit cast
// to RHS-type and the result is casted back to LHS-type: static_cast<LHSTy>( static_cast<RHSTy>(LHS) + RHS )
if(const auto resultingType = GetGlobalCI().getSema().PrepareScalarCast(res, stmt->getComputationLHSType());
resultingType != CK_NoOp) {
const QualType castDestType = stmt->getComputationLHSType();
FormatCast(kwStaticCast, castDestType, stmt->getLHS(), resultingType);
} else {
InsertArg(stmt->getLHS());
}
});

mOutputFormatHelper.Append(
" ", BinaryOperator::getOpcodeStr(BinaryOperator::getOpForCompoundAssignment(stmt->getOpcode())), " ");

const bool needRHSParens{isa<BinaryOperator>(stmt->getRHS()->IgnoreImpCasts())};
WrapInParensIfNeeded(needRHSParens, [&] { InsertArg(stmt->getRHS()); });

if(needCast) {
mOutputFormatHelper.Append(")");
}
}
//-----------------------------------------------------------------------------

void CodeGenerator::InsertArg(const CXXRewrittenBinaryOperator* stmt)
{
LAMBDA_SCOPE_HELPER(BinaryOperator);
Expand Down
1 change: 1 addition & 0 deletions CodeGeneratorTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ SUPPORTED_STMT(CXXMemberCallExpr)
SUPPORTED_STMT(CXXThisExpr)
SUPPORTED_STMT(CXXConstructExpr)
SUPPORTED_STMT(CXXInheritedCtorInitExpr)
SUPPORTED_STMT(CompoundAssignOperator)
SUPPORTED_STMT(BinaryOperator)
SUPPORTED_STMT(CXXNamedCastExpr)
SUPPORTED_STMT(CXXFunctionalCastExpr)
Expand Down
8 changes: 8 additions & 0 deletions Insights.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ const ASTContext& GetGlobalAST()
}
//-----------------------------------------------------------------------------

static const CompilerInstance* gCI{};
const CompilerInstance& GetGlobalCI()
{
return *gCI;
}
//-----------------------------------------------------------------------------

class CppInsightASTConsumer final : public ASTConsumer
{
public:
Expand Down Expand Up @@ -156,6 +163,7 @@ class CppInsightFrontendAction final : public ASTFrontendAction

std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance& CI, StringRef /*file*/) override
{
gCI = &CI;
mRewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts());
return std ::make_unique<CppInsightASTConsumer>(mRewriter);
}
Expand Down
7 changes: 6 additions & 1 deletion Insights.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@

namespace clang {
class ASTContext;
}
class CompilerInstance;
} // namespace clang
//-----------------------------------------------------------------------------

/// \brief Global C++ Insights command line options.
Expand All @@ -30,4 +31,8 @@ extern const InsightsOptions& GetInsightsOptions();
extern const clang::ASTContext& GetGlobalAST();
//-----------------------------------------------------------------------------

/// \brief Get access to the CompilerInstance
extern const clang::CompilerInstance& GetGlobalCI();
//-----------------------------------------------------------------------------

#endif /* INSIGHTS_H */
2 changes: 1 addition & 1 deletion tests/Class2Test.expect
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class Test

inline Test & operator+=(const Test & rhs)
{
this->mV += rhs.mV;
this->mV = this->mV + rhs.mV;
return *this;
}

Expand Down
6 changes: 3 additions & 3 deletions tests/ClassOperatorHandlerTest.expect
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ class Test

inline Test & operator+=(const Test & rhs)
{
this->mX += rhs.mX;
this->mX = this->mX + rhs.mX;
return *this;
}

inline Test & operator<<(const Test & rhs)
{
this->mX += rhs.mX;
this->mX = this->mX + rhs.mX;
return *this;
}

Expand Down Expand Up @@ -123,7 +123,7 @@ namespace Hello

inline Fest & operator<<(const Fest & rhs)
{
this->mX += rhs.mX;
this->mX = this->mX + rhs.mX;
return *this;
}

Expand Down
2 changes: 1 addition & 1 deletion tests/ClassTest.expect
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class Test

inline Test & operator+=(const Test & rhs)
{
this->mV += rhs.mV;
this->mV = this->mV + rhs.mV;
return *this;
}

Expand Down
43 changes: 43 additions & 0 deletions tests/CompoundAssignOperatorTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
int main()
{
char c = 1;
short s = 3;
int i = 2;
float f = 2.9f;
double d = 3.1;

// char
c += c;
c += s;
c += i;
c += f;
c += d;

// short
s += c;
s += s;
s += i;
s += f;
s += d;

// int
i += c;
i += s;
i += i;
i += f;
i += d;

// float
f += c;
f += s;
f += i;
f += f;
f += d;

// double
d += c;
d += s;
d += i;
d += f;
d += d;
}
34 changes: 34 additions & 0 deletions tests/CompoundAssignOperatorTest.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
int main()
{
char c = 1;
short s = 3;
int i = 2;
float f = 2.9000001F;
double d = 3.1000000000000001;
c = static_cast<char>(static_cast<int>(c) + static_cast<int>(c));
c = static_cast<char>(static_cast<int>(c) + static_cast<int>(s));
c = static_cast<char>(static_cast<int>(c) + i);
c = static_cast<char>(static_cast<float>(c) + f);
c = static_cast<char>(static_cast<double>(c) + d);
s = static_cast<short>(static_cast<int>(s) + static_cast<int>(c));
s = static_cast<short>(static_cast<int>(s) + static_cast<int>(s));
s = static_cast<short>(static_cast<int>(s) + i);
s = static_cast<short>(static_cast<float>(s) + f);
s = static_cast<short>(static_cast<double>(s) + d);
i = i + static_cast<int>(c);
i = i + static_cast<int>(s);
i = i + i;
i = static_cast<int>(static_cast<float>(i) + f);
i = static_cast<int>(static_cast<double>(i) + d);
f = f + static_cast<float>(static_cast<int>(c));
f = f + static_cast<float>(static_cast<int>(s));
f = f + static_cast<float>(i);
f = f + f;
f = static_cast<float>(static_cast<double>(f) + d);
d = d + static_cast<double>(static_cast<int>(c));
d = d + static_cast<double>(static_cast<int>(s));
d = d + static_cast<double>(i);
d = d + static_cast<double>(f);
d = d + d;
}

2 changes: 1 addition & 1 deletion tests/FoldExpressionTest.expect
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ int main()
/* PASSED: static_assert(static_cast<int>(true) == static_cast<int>(logicalOr(true, true, true, false))); */
/* PASSED: static_assert(4 == comma(1, 2, 3, 4)); */
int x = 4;
x /= 2;
x = x / 2;
}


4 changes: 2 additions & 2 deletions tests/ForStmtMultipleInitsTest.expect
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ int main()
{
int x = 0;
for(int i = 0, y = 2, t = 4, o = 5; i < 20; ++i) {
x += i;
x = x + i;
}

for(int * i = &x, *y = &x, *z = &x; i; ++i) {
x += *i;
x = x + *i;
}

}
Expand Down
4 changes: 2 additions & 2 deletions tests/ForStmtWithLambdaInInitTest.expect
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ int main()
} __lambda_7_17{x};

for(int i = __lambda_7_17.operator()(); i < 20; ++i) {
x += i;
x = x + i;
}


Expand Down Expand Up @@ -65,7 +65,7 @@ int main()
} __lambda_11_43{x};

for(int i = __lambda_11_17.operator()(), z = __lambda_11_43.operator()(); i < 20; ++i) {
x += i;
x = x + i;
}


Expand Down
18 changes: 18 additions & 0 deletions tests/Issue405.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include <complex>
using namespace std;

int main () {

int q = 2;
++q;
q--;
q += 2.0;

complex<int> com1{3,4};
complex<int> com2(com1);

com1 += com2;
com1 = com1 + com2;;

return 0;
}
17 changes: 17 additions & 0 deletions tests/Issue405.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include <complex>
using namespace std;

int main()
{
int q = 2;
++q;
q--;
q = static_cast<int>(static_cast<double>(q) + 2.0);
complex<int> com1 = std::complex<int>{3, 4};
complex<int> com2 = std::complex<int>(com1);
com1.operator+=(com2);
com1.operator=(std::operator+(com1, com2));
;
return 0;
}

8 changes: 4 additions & 4 deletions tests/Issue45Example.expect
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ int main()
{
int x = 0;
for(; x < 20; ++x) {
x += x;
x = x + x;
}

for(int i = 0; x < 20; ++x) {
x += i;
x = x + i;
}

for(int i = 0, y = 2, t = 4, o = 5; i < 20; ++i) {
x += i;
x = x + i;
}

for(int * i = &x, *y = &x; i; ++i) {
x += *i;
x = x + *i;
}

for(; ; ) {
Expand Down
8 changes: 4 additions & 4 deletions tests/Issue45Example11.expect
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@ int main()
{
int x = 0;
for(; x < 20; ++x) {
x += x;
x = x + x;
}

for(int i = 0; x < 20; ++x) {
x += i;
x = x + i;
}

for(int i = 0, y = 2, t = 4, o = 5; i < 20; ++i) {
x += i;
x = x + i;
}

for(int * i = &x, *y = &x; i; ++i) {
x += *i;
x = x + *i;
}

for(; ; ) {
Expand Down
8 changes: 4 additions & 4 deletions tests/Issue45ExampleFor2While.expect
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ int main()
int x = 0;
{
while(x < 20) {
x += x;
x = x + x;
++x;
}

Expand All @@ -13,7 +13,7 @@ int main()
{
int i = 0;
while(x < 20) {
x += i;
x = x + i;
++x;
}

Expand All @@ -25,7 +25,7 @@ int main()
int t = 4;
int o = 5;
while(i < 20) {
x += i;
x = x + i;
++i;
}

Expand All @@ -35,7 +35,7 @@ int main()
int * i = &x;
int * y = &x;
while(i) {
x += *i;
x = x + *i;
++i;
}

Expand Down
Loading

0 comments on commit 511bb4e

Please sign in to comment.