Index: clang/lib/StaticAnalyzer/Core/ExprEngine.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -2603,9 +2603,22 @@ // operator&. return; } - if (isa(D)) { - // FIXME: proper support for bound declarations. - // For now, let's just prevent crashing. + if (const auto *BD = dyn_cast(D)) { + const auto *DD = cast(BD->getDecomposedDecl()); + + if (const auto *ME = dyn_cast(BD->getBinding())) { + const auto *Field = cast(ME->getMemberDecl()); + + SVal Base = state->getLValue(DD, LCtx); + if (DD->getType()->isReferenceType()) { + Base = state->getSVal(Base.getAsRegion()); + } + + SVal V = state->getLValue(Field, Base); + + Bldr.generateNode(Ex, Pred, state->BindExpr(Ex, LCtx, V)); + } + return; } Index: clang/test/Analysis/uninit-structured-binding-struct.cpp =================================================================== --- /dev/null +++ clang/test/Analysis/uninit-structured-binding-struct.cpp @@ -0,0 +1,74 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core -std=c++17 -verify -analyzer-output=text %s + +void clang_analyzer_eval(bool); + +struct s { + int a; + int b; +}; + +void a(void) { + s tst; + + auto [i, j] = tst; + + int x = i; + // expected-warning@-1{{Assigned value is garbage or undefined}} + // expected-note@-2{{Assigned value is garbage or undefined}} +} + +void b(void) { + s tst; + tst.a = 1; + + auto [i, j] = tst; + + clang_analyzer_eval(i == 1); + int y = j; + // expected-warning@-1{{Assigned value is garbage or undefined}} + // expected-note@-2{{Assigned value is garbage or undefined}} +} + +void c(void) { + s tst; + + auto &[i, j] = tst; + + int x = i; + // expected-warning@-1{{Assigned value is garbage or undefined}} + // expected-note@-2{{Assigned value is garbage or undefined}} +} + +void d(void) { + s tst; + tst.a = 1; + + auto &[i, j] = tst; + + clang_analyzer_eval(i == 1); + int y = j; + // expected-warning@-1{{Assigned value is garbage or undefined}} + // expected-note@-2{{Assigned value is garbage or undefined}} +} + +void e(void) { + s tst; + + auto &&[i, j] = tst; + + int x = i; + // expected-warning@-1{{Assigned value is garbage or undefined}} + // expected-note@-2{{Assigned value is garbage or undefined}} +} + +void f(void) { + s tst; + tst.a = 1; + + auto &&[i, j] = tst; + + clang_analyzer_eval(i == 1); + int y = j; + // expected-warning@-1{{Assigned value is garbage or undefined}} + // expected-note@-2{{Assigned value is garbage or undefined}} +}