@@ -987,10 +987,11 @@ static void DiagUninitUse(Sema &S, const VarDecl *VD, const UninitUse &Use,
987
987
}
988
988
989
989
// / Diagnose uninitialized const reference usages.
990
- static void DiagnoseUninitializedConstRefUse (Sema &S, const VarDecl *VD,
990
+ static bool DiagnoseUninitializedConstRefUse (Sema &S, const VarDecl *VD,
991
991
const UninitUse &Use) {
992
992
S.Diag (Use.getUser ()->getBeginLoc (), diag::warn_uninit_const_reference)
993
993
<< VD->getDeclName () << Use.getUser ()->getSourceRange ();
994
+ return !S.getDiagnostics ().isLastDiagnosticIgnored ();
994
995
}
995
996
996
997
// / DiagnoseUninitializedUse -- Helper function for diagnosing uses of an
@@ -1022,7 +1023,7 @@ static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,
1022
1023
if (CR.doesContainReference ()) {
1023
1024
S.Diag (DRE->getBeginLoc (), diag::warn_uninit_self_reference_in_init)
1024
1025
<< VD->getDeclName () << VD->getLocation () << DRE->getSourceRange ();
1025
- return true ;
1026
+ return !S. getDiagnostics (). isLastDiagnosticIgnored () ;
1026
1027
}
1027
1028
}
1028
1029
@@ -1045,7 +1046,7 @@ static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,
1045
1046
S.Diag (VD->getBeginLoc (), diag::note_var_declared_here)
1046
1047
<< VD->getDeclName ();
1047
1048
1048
- return true ;
1049
+ return !S. getDiagnostics (). isLastDiagnosticIgnored () ;
1049
1050
}
1050
1051
1051
1052
namespace {
@@ -1559,43 +1560,7 @@ class UninitValsDiagReporter : public UninitVariablesHandler {
1559
1560
UsesVec *vec = V.getPointer ();
1560
1561
bool hasSelfInit = V.getInt ();
1561
1562
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);
1599
1564
1600
1565
// Release the uses vector.
1601
1566
delete vec;
@@ -1612,6 +1577,49 @@ class UninitValsDiagReporter : public UninitVariablesHandler {
1612
1577
U.getKind () == UninitUse::AfterDecl;
1613
1578
});
1614
1579
}
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
+ }
1615
1623
};
1616
1624
1617
1625
// / Inter-procedural data for the called-once checker.
0 commit comments