1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
7 * This file is distributed under the University of Illinois Open Source
8 * License. See LICENSE.TXT for details.
12 #include "tutorial2.hxx"
15 This is a compile check.
17 Warns about if statements with a comparison followed by literal return false:
25 Tutorial2::Tutorial2( const InstantiationData
& data
)
26 : FilteringPlugin( data
)
32 // The Clang AST helper class will call VisitIfStmt for every if statement.
33 TraverseDecl( compiler
.getASTContext().getTranslationUnitDecl());
36 // This function is called for every if statement.
37 bool Tutorial2::VisitIfStmt( const IfStmt
* ifstmt
)
39 if( ignoreLocation( ifstmt
))
41 // Check if the condition of the if statement is a binary operator.
42 if( const BinaryOperator
* oper
= dyn_cast
< BinaryOperator
>( ifstmt
->getCond()))
44 // And if it's operator==.
45 if( oper
->getOpcode() == BO_EQ
)
47 // Now check if the sub-statement is 'return false'.
48 const Stmt
* warn
= NULL
; // The return statement (for the warning message).
49 // Check if the sub-statement is directly 'return false;'.
50 if( isReturnFalse( ifstmt
->getThen()))
51 warn
= ifstmt
->getThen();
52 // Check if the sub-statement is '{ return false; }'
53 else if( const CompoundStmt
* compound
= dyn_cast
< CompoundStmt
>( ifstmt
->getThen()))
55 if( compound
->size() == 1 ) // one statement
56 if( isReturnFalse( *compound
->body_begin())) // check the one sub-statement
57 warn
= *compound
->body_begin();
59 if( warn
!= NULL
) // there is a return statement to warn about.
61 report( DiagnosticsEngine::Warning
,
62 "returning false after if with equality comparison",
63 cast
< ReturnStmt
>( warn
)->getRetValue()->getLocStart()) // the 'false' in the return
64 << warn
->getSourceRange();
65 // Also add a note showing the if statement.
66 report( DiagnosticsEngine::Note
,
67 "the if statement is here",
68 ifstmt
->getLocStart());
75 bool Tutorial2::isReturnFalse( const Stmt
* stmt
)
77 // Is it return statement?
78 if( const ReturnStmt
* returnstmt
= dyn_cast
< ReturnStmt
>( stmt
))
80 // dyn_cast_or_null<> can also be passed NULL, unlike dyn_cast<>
81 if( const CXXBoolLiteralExpr
* boolliteral
= dyn_cast_or_null
< CXXBoolLiteralExpr
>( returnstmt
->getRetValue()))
83 if( boolliteral
->getValue() == false )
90 // Register the plugin action with the LO plugin handling.
91 static Plugin::Registration
< Tutorial2
> tutorial2( "tutorial2" );
95 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */