Skip to content

Commit 7fd255f

Browse files
danix800tstellar
authored andcommitted
[analyzer] Explicit cast on customized offsetof should not be ignored when evaluating as const
If ignored, the subexpr is a UnaryOperator (&) which cannot be evaluated (assertion failed). #define offsetof(type,memb) ((unsigned long)&((type*)0)->memb) Patch By danix800! Differential Revision: https://reviews.llvm.org/D144780 (cherry picked from commit 53f7542)
1 parent f2ee0b2 commit 7fd255f

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

clang/lib/StaticAnalyzer/Core/BugReporter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ PathDiagnosticPieceRef PathDiagnosticBuilder::generateDiagForSwitchOP(
766766
case Stmt::CaseStmtClass: {
767767
os << "Control jumps to 'case ";
768768
const auto *Case = cast<CaseStmt>(S);
769-
const Expr *LHS = Case->getLHS()->IgnoreParenCasts();
769+
const Expr *LHS = Case->getLHS()->IgnoreParenImpCasts();
770770

771771
// Determine if it is an enum.
772772
bool GetRawInt = true;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -triple x86_64-linux-gnu -Wno-shift-count-overflow -verify %s
2+
3+
#define offsetof(type,memb) ((unsigned long)&((type*)0)->memb)
4+
5+
typedef struct {
6+
unsigned long guest_counter;
7+
unsigned int guest_fpc;
8+
} S;
9+
10+
// no crash
11+
int left_shift_overflow_no_crash(unsigned int i) {
12+
unsigned shift = 323U; // expected-note{{'shift' initialized to 323}}
13+
switch (i) { // expected-note{{Control jumps to 'case 8:' at line 14}}
14+
case offsetof(S, guest_fpc):
15+
return 3 << shift; // expected-warning{{The result of the left shift is undefined due to shifting by '323', which is greater or equal to the width of type 'int'}}
16+
// expected-note@-1{{The result of the left shift is undefined due to shifting by '323', which is greater or equal to the width of type 'int'}}
17+
default:
18+
break;
19+
}
20+
21+
return 0;
22+
}

0 commit comments

Comments
 (0)