Author: Rajveer Singh Bharadwaj Date: 2024-05-13T13:43:35+02:00 New Revision: efe91cf78bccda90637c817e3e592b5f34e891d0
URL: https://github.com/llvm/llvm-project/commit/efe91cf78bccda90637c817e3e592b5f34e891d0 DIFF: https://github.com/llvm/llvm-project/commit/efe91cf78bccda90637c817e3e592b5f34e891d0.diff LOG: [clang][analyzer] Check for label location bindings in `DereferenceChecker` (#91119) Resolves #89264 Values should not be stored in addresses of labels, this throws a fatal error when this happens. --------- Co-authored-by: Balazs Benics <benicsbal...@gmail.com> Added: Modified: clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp clang/test/Analysis/gh-issue-89185.c Removed: ################################################################################ diff --git a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp index 1cebfbbee77da..0355eede75eae 100644 --- a/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/DereferenceChecker.cpp @@ -31,11 +31,13 @@ class DereferenceChecker : public Checker< check::Location, check::Bind, EventDispatcher<ImplicitNullDerefEvent> > { - enum DerefKind { NullPointer, UndefinedPointerValue }; + enum DerefKind { NullPointer, UndefinedPointerValue, AddressOfLabel }; BugType BT_Null{this, "Dereference of null pointer", categories::LogicError}; BugType BT_Undef{this, "Dereference of undefined pointer value", categories::LogicError}; + BugType BT_Label{this, "Dereference of the address of a label", + categories::LogicError}; void reportBug(DerefKind K, ProgramStateRef State, const Stmt *S, CheckerContext &C) const; @@ -167,6 +169,11 @@ void DereferenceChecker::reportBug(DerefKind K, ProgramStateRef State, DerefStr1 = " results in an undefined pointer dereference"; DerefStr2 = " results in a dereference of an undefined pointer value"; break; + case DerefKind::AddressOfLabel: + BT = &BT_Label; + DerefStr1 = " results in an undefined pointer dereference"; + DerefStr2 = " results in a dereference of an address of a label"; + break; }; // Generate an error node. @@ -287,6 +294,12 @@ void DereferenceChecker::checkBind(SVal L, SVal V, const Stmt *S, if (V.isUndef()) return; + // One should never write to label addresses. + if (auto Label = L.getAs<loc::GotoLabel>()) { + reportBug(DerefKind::AddressOfLabel, C.getState(), S, C); + return; + } + const MemRegion *MR = L.getAsRegion(); const TypedValueRegion *TVR = dyn_cast_or_null<TypedValueRegion>(MR); if (!TVR) diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index 984755fa7e502..487a3bd16b674 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -113,6 +113,9 @@ const Expr *bugreporter::getDerefExpr(const Stmt *S) { // Pointer arithmetic: '*(x + 2)' -> 'x') etc. if (const Expr *Inner = peelOffPointerArithmetic(B)) { E = Inner; + } else if (B->isAssignmentOp()) { + // Follow LHS of assignments: '*p = 404' -> 'p'. + E = B->getLHS(); } else { // Probably more arithmetic can be pattern-matched here, // but for now give up. diff --git a/clang/test/Analysis/gh-issue-89185.c b/clang/test/Analysis/gh-issue-89185.c index 8a907f198a5fd..49526d2daa866 100644 --- a/clang/test/Analysis/gh-issue-89185.c +++ b/clang/test/Analysis/gh-issue-89185.c @@ -1,14 +1,13 @@ -// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-output text -verify %s -void clang_analyzer_dump(char); -void clang_analyzer_dump_ptr(char*); +void clang_analyzer_warnIfReached(void); // https://github.com/llvm/llvm-project/issues/89185 void binding_to_label_loc() { - char *b = &&MyLabel; + char *b = &&MyLabel; // expected-note {{'b' initialized here}} MyLabel: - *b = 0; // no-crash - clang_analyzer_dump_ptr(b); // expected-warning {{&&MyLabel}} - clang_analyzer_dump(*b); // expected-warning {{Unknown}} - // FIXME: We should never reach here, as storing to a label is invalid. + *b = 0; + // expected-warning@-1 {{Dereference of the address of a label}} + // expected-note@-2 {{Dereference of the address of a label}} + clang_analyzer_warnIfReached(); // no-warning: Unreachable due to fatal error. } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits