giannicrivello created this revision. giannicrivello added reviewers: NoQ, tbaeder. giannicrivello added a project: clang. Herald added subscribers: steakhal, martong. Herald added a reviewer: sscalpone. Herald added projects: Flang, All. giannicrivello requested review of this revision. Herald added subscribers: cfe-commits, jdoerfert.
Patched llvm-project/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp to account for the user passing a nullptr to the implementation dependent function printf(). Invoked with `bin/scan-build -enable-checker optin.portability bin/clang -g test.cpp` where the contents of test.cpp is: c++ #include <stdio.h> #include <stdlib.h> int main() { int *p = nullptr; printf("%p", p); } now produces the warning: test.cpp:6:5: warning: Passing a null pointer to printf() is implementation dependant. Portability warning [optin.portability.UnixAPI] printf("%p", p); ^~~~~~~~~~~~~~~ 1 warning generated. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D139604 Files: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp flang/docs/Extensions.md flang/lib/Parser/Fortran-parsers.cpp flang/test/Parser/missing-colons.f90
Index: flang/test/Parser/missing-colons.f90 =================================================================== --- /dev/null +++ flang/test/Parser/missing-colons.f90 @@ -0,0 +1,13 @@ +! RUN: %flang_fc1 -fsyntax-only -pedantic %s 2>&1 | FileCheck %s +module m + type t + contains +!CHECK: portability: type-bound procedure statement should have '::' if it has '=>' + procedure p => sub + end type + contains + subroutine sub(x) + class(t), intent(in) :: x + end subroutine +end module + Index: flang/lib/Parser/Fortran-parsers.cpp =================================================================== --- flang/lib/Parser/Fortran-parsers.cpp +++ flang/lib/Parser/Fortran-parsers.cpp @@ -522,6 +522,9 @@ // R749 type-bound-procedure-stmt -> // PROCEDURE [[, bind-attr-list] ::] type-bound-proc-decl-list | // PROCEDURE ( interface-name ) , bind-attr-list :: binding-name-list +// The "::" is required by the standard (C768) in the first production if +// any type-bound-proc-decl has a "=>', but it's not strictly necessary to +// avoid a bad parse. TYPE_CONTEXT_PARSER("type bound PROCEDURE statement"_en_US, "PROCEDURE" >> (construct<TypeBoundProcedureStmt>( @@ -531,6 +534,15 @@ "," >> nonemptyList(Parser<BindAttr>{}), ok), localRecovery("expected list of binding names"_err_en_US, "::" >> listOfNames, SkipTo<'\n'>{}))) || + construct<TypeBoundProcedureStmt>(construct< + TypeBoundProcedureStmt::WithoutInterface>( + pure<std::list<BindAttr>>(), + nonemptyList( + "expected type bound procedure declarations"_err_en_US, + construct<TypeBoundProcDecl>(name, + maybe(extension<LanguageFeature::MissingColons>( + "type-bound procedure statement should have '::' if it has '=>'"_port_en_US, + "=>" >> name)))))) || construct<TypeBoundProcedureStmt>( construct<TypeBoundProcedureStmt::WithoutInterface>( optionalListBeforeColons(Parser<BindAttr>{}), Index: flang/docs/Extensions.md =================================================================== --- flang/docs/Extensions.md +++ flang/docs/Extensions.md @@ -242,6 +242,11 @@ compilers, so it is not supported. * f18 doesn't impose a limit on the number of continuation lines allowed for a single statement. +* When a type-bound procedure declaration statement has neither interface + nor attributes, the "::" before the bindings is optional, even + if a binding has renaming with "=> proc". + The colons are not necessary for an unambiguous parse, C768 + notwithstanding. ### Extensions supported when enabled by options Index: clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp =================================================================== --- clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp +++ clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp @@ -11,11 +11,12 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/Basic/TargetInfo.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" @@ -59,9 +60,11 @@ }; -class UnixAPIPortabilityChecker : public Checker< check::PreStmt<CallExpr> > { +class UnixAPIPortabilityChecker + : public Checker<check::PreStmt<CallExpr>, check::PostCall> { public: void checkPreStmt(const CallExpr *CE, CheckerContext &C) const; + void checkPostCall(const CallEvent &Call, CheckerContext &C) const; private: mutable std::unique_ptr<BugType> BT_mallocZero; @@ -493,6 +496,41 @@ CheckVallocZero(C, CE); } +void UnixAPIPortabilityChecker::checkPostCall(const CallEvent &Call, + CheckerContext &C) const { + + auto State = C.getState(); + + const IdentifierInfo *II = Call.getCalleeIdentifier(); + if (!II) + return; + if (!II->isStr("printf")) + return; + + if (!BT_mallocZero) + BT_mallocZero.reset(new BugType(this, "Call to printf", "Example checker")); + + for (unsigned int i = 0; i < Call.getNumArgs(); i++) { + const auto *Arg = Call.getArgExpr(i); + if (!Arg) + return; + const auto *LC = C.getLocationContext(); + auto Val = State->getSVal(Arg, LC); + if (Val.isZeroConstant()) { + ExplodedNode *N = C.generateErrorNode(); + + // Further better the diagnostic message by adding a bug report visitor + auto Report = std::make_unique<PathSensitiveBugReport>( + *BT_mallocZero, + "Passing a null pointer to printf() is implementation dependant. " + "Portability warning.", + N); + Report->addRange(Arg->getSourceRange()); + C.emitReport(std::move(Report)); + } + } +} + //===----------------------------------------------------------------------===// // Registration. //===----------------------------------------------------------------------===// Index: clang/include/clang/StaticAnalyzer/Checkers/Checkers.td =================================================================== --- clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -1667,7 +1667,7 @@ def UnixAPIPortabilityChecker : Checker<"UnixAPI">, HelpText<"Finds implementation-defined behavior in UNIX/Posix functions">, Documentation<NotDocumented>; - + } // end optin.portability //===----------------------------------------------------------------------===//
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits