@@ -987,10 +987,11 @@ static void DiagUninitUse(Sema &S, const VarDecl *VD, const UninitUse &Use,
987987}
988988
989989// / Diagnose uninitialized const reference usages.
990- static void DiagnoseUninitializedConstRefUse (Sema &S, const VarDecl *VD,
990+ static bool DiagnoseUninitializedConstRefUse (Sema &S, const VarDecl *VD,
991991 const UninitUse &Use) {
992992 S.Diag (Use.getUser ()->getBeginLoc (), diag::warn_uninit_const_reference)
993993 << VD->getDeclName () << Use.getUser ()->getSourceRange ();
994+ return !S.getDiagnostics ().isLastDiagnosticIgnored ();
994995}
995996
996997// / DiagnoseUninitializedUse -- Helper function for diagnosing uses of an
@@ -1022,7 +1023,7 @@ static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,
10221023 if (CR.doesContainReference ()) {
10231024 S.Diag (DRE->getBeginLoc (), diag::warn_uninit_self_reference_in_init)
10241025 << VD->getDeclName () << VD->getLocation () << DRE->getSourceRange ();
1025- return true ;
1026+ return !S. getDiagnostics (). isLastDiagnosticIgnored () ;
10261027 }
10271028 }
10281029
@@ -1045,7 +1046,7 @@ static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,
10451046 S.Diag (VD->getBeginLoc (), diag::note_var_declared_here)
10461047 << VD->getDeclName ();
10471048
1048- return true ;
1049+ return !S. getDiagnostics (). isLastDiagnosticIgnored () ;
10491050}
10501051
10511052namespace {
@@ -1559,43 +1560,7 @@ class UninitValsDiagReporter : public UninitVariablesHandler {
15591560 UsesVec *vec = V.getPointer ();
15601561 bool hasSelfInit = V.getInt ();
15611562
1562- // Specially handle the case where we have uses of an uninitialized
1563- // variable, but the root cause is an idiomatic self-init. We want
1564- // to report the diagnostic at the self-init since that is the root cause.
1565- if (!vec->empty () && hasSelfInit && hasAlwaysUninitializedUse (vec))
1566- DiagnoseUninitializedUse (S, vd,
1567- UninitUse (vd->getInit ()->IgnoreParenCasts (),
1568- /* isAlwaysUninit */ true ),
1569- /* alwaysReportSelfInit */ true );
1570- else {
1571- // Sort the uses by their SourceLocations. While not strictly
1572- // guaranteed to produce them in line/column order, this will provide
1573- // a stable ordering.
1574- llvm::sort (*vec, [](const UninitUse &a, const UninitUse &b) {
1575- // Move ConstRef uses to the back.
1576- if (a.isConstRefUse () != b.isConstRefUse ())
1577- return b.isConstRefUse ();
1578- // Prefer a more confident report over a less confident one.
1579- if (a.getKind () != b.getKind ())
1580- return a.getKind () > b.getKind ();
1581- return a.getUser ()->getBeginLoc () < b.getUser ()->getBeginLoc ();
1582- });
1583-
1584- for (const auto &U : *vec) {
1585- if (U.isConstRefUse ()) {
1586- DiagnoseUninitializedConstRefUse (S, vd, U);
1587- break ;
1588- }
1589-
1590- // If we have self-init, downgrade all uses to 'may be uninitialized'.
1591- UninitUse Use = hasSelfInit ? UninitUse (U.getUser (), false ) : U;
1592-
1593- if (DiagnoseUninitializedUse (S, vd, Use))
1594- // Skip further diagnostics for this variable. We try to warn only
1595- // on the first point at which a variable is used uninitialized.
1596- break ;
1597- }
1598- }
1563+ diagnoseUnitializedVar (vd, hasSelfInit, vec);
15991564
16001565 // Release the uses vector.
16011566 delete vec;
@@ -1612,6 +1577,49 @@ class UninitValsDiagReporter : public UninitVariablesHandler {
16121577 U.getKind () == UninitUse::AfterDecl;
16131578 });
16141579 }
1580+
1581+ // Print the diagnostic for the variable. We try to warn only on the first
1582+ // point at which a variable is used uninitialized. After the first
1583+ // diagnostic is printed, further diagnostics for this variable are skipped.
1584+ void diagnoseUnitializedVar (const VarDecl *vd, bool hasSelfInit,
1585+ UsesVec *vec) {
1586+ // Specially handle the case where we have uses of an uninitialized
1587+ // variable, but the root cause is an idiomatic self-init. We want
1588+ // to report the diagnostic at the self-init since that is the root cause.
1589+ if (hasSelfInit && hasAlwaysUninitializedUse (vec)) {
1590+ if (DiagnoseUninitializedUse (S, vd,
1591+ UninitUse (vd->getInit ()->IgnoreParenCasts (),
1592+ /* isAlwaysUninit=*/ true ),
1593+ /* alwaysReportSelfInit=*/ true ))
1594+ return ;
1595+ }
1596+
1597+ // Sort the uses by their SourceLocations. While not strictly
1598+ // guaranteed to produce them in line/column order, this will provide
1599+ // a stable ordering.
1600+ llvm::sort (*vec, [](const UninitUse &a, const UninitUse &b) {
1601+ // Prefer the direct use of an uninitialized variable over its use via
1602+ // constant reference.
1603+ if (a.isConstRefUse () != b.isConstRefUse ())
1604+ return b.isConstRefUse ();
1605+ // Prefer a more confident report over a less confident one.
1606+ if (a.getKind () != b.getKind ())
1607+ return a.getKind () > b.getKind ();
1608+ return a.getUser ()->getBeginLoc () < b.getUser ()->getBeginLoc ();
1609+ });
1610+
1611+ for (const auto &U : *vec) {
1612+ if (U.isConstRefUse ()) {
1613+ if (DiagnoseUninitializedConstRefUse (S, vd, U))
1614+ return ;
1615+ } else {
1616+ // If we have self-init, downgrade all uses to 'may be uninitialized'.
1617+ UninitUse Use = hasSelfInit ? UninitUse (U.getUser (), false ) : U;
1618+ if (DiagnoseUninitializedUse (S, vd, Use))
1619+ return ;
1620+ }
1621+ }
1622+ }
16151623};
16161624
16171625// / Inter-procedural data for the called-once checker.
0 commit comments