Create CFG for initializers and perform analysis based warnings on global variables
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
- Build Status
Buildable 34016 Build 34015: arc lint + arc unit
Event Timeline
clang/include/clang/Sema/AnalysisBasedWarnings.h | ||
---|---|---|
111 | Fix indentation. | |
clang/lib/Sema/AnalysisBasedWarnings.cpp | ||
2007 | Should PossiblyUnreachableDiags be const? Also, fix indentation. | |
2015 | How about returning early if PossiblyUnreachableDiags here is empty? That'll avoid putting the entire logic of this function in the true branch. | |
2031 | getCFGReachablityAnalysis has a typo. It's missing an 'i'. Consider fixing this in a separate patch. | |
2051 | Rewrite this as the else clause for if (AC.getCFG())? In the current structure, it's not immediately clear that flushDiagnostics is called iff AC.getCFG() fails to return a valid CFG. Upon further reading, this seems to be refactored from another function below so it probably makes sense to leave it as-is. |
clang/include/clang/Sema/AnalysisBasedWarnings.h | ||
---|---|---|
101 | git-clang-format HEAD~<number of commits> The formal parameter should be abbreviated, maybe PUD? | |
110 | How about making this a proper method of AnalysisBasedWarnings rather than a free floating function that's only ever called from other methods of AnalysisBasedWarnings? That way you don't have to pass in a Sema. | |
clang/lib/Analysis/AnalysisDeclContext.cpp | ||
124 | The const_cast doesn't look necessary here. Is it? | |
clang/lib/Sema/AnalysisBasedWarnings.cpp | ||
2012 | having the full namespace spelled out here in the definition smells funny. Is there a pair of namespace blocks below for clang and sema where the definition of emitPossiblyUnreachableDiags could be moved into? Actually looking at the file, I see you simply matched the existing style, but line 49 currently has a using statement that should inject the clang namespace into the current scope. That's why you see sema:: used in other places in this translation unit without the clang namespace prefix. The whole file should remove the clang:: prefixes or additionally replace the using statement with explicit namespace blocks. | |
2260 | PUD | |
2275 | If you make emitPossiblyUnreachableDiags then it doesn't need all the prefixes. | |
clang/lib/Sema/SemaDeclCXX.cpp | ||
347 | Use punctuation in your comments. | |
clang/lib/Sema/SemaExpr.cpp | ||
16678 | Punctuation. | |
clang/test/Sema/warn-unreachable-warning-var-decl.cpp | ||
39–40 | ok and also ok can probably be removed? |
clang/lib/Analysis/AnalysisDeclContext.cpp | ||
---|---|---|
124 | VD->getInit returns a const Expr *. In order to remove the const_cast I would need to make getBody() const and every call to getBody(). The change required to add const seemed too large to be included in this patch. |
clang/lib/Sema/SemaDeclCXX.cpp | ||
---|---|---|
352 | We may need to delay the diagnostics here until the default argument is *used*: if a default argument references a template instantiation, the instantiation is not performed until that point, which may mean that our semantic checking can't complete correctly until use. | |
clang/lib/Sema/SemaExpr.cpp | ||
16699 | It's not correct to assume that the last declaration in the context is the right one to be considering here. Instead, you should track whether you're in a variable initializer (and for what) in Sema. Examples: int x = ([]{}(), x); // in C++; last decl is the lambda int y = (struct Q { int n; }){y}; // in C; last decl is the struct |
clang/include/clang/Sema/Sema.h | ||
---|---|---|
1689 ↗ | (On Diff #211213) | might be nice to return the result, but maybe YAGNI? |
clang/lib/Sema/AnalysisBasedWarnings.cpp | ||
---|---|---|
2061 | is clang namespace required here? |
clang/lib/Sema/SemaDeclCXX.cpp | ||
---|---|---|
352 | Currently this patch really only works with globals. There are many places where the following check is made instead of calling ParseInitializer. These should probably be rewritten into a single function and do something similar with pushing/popping declarations. Not sure if that change should be made in this patch or not. if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace)) { Diag(Tok, diag::warn_cxx98_compat_generalized_initializer_lists); DefArgResult = ParseBraceInitializer(); } else DefArgResult = ParseAssignmentExpression(); |
clang/include/clang/Sema/Sema.h | ||
---|---|---|
1684–1686 ↗ | (On Diff #211224) | I don't think a simple list of these can work. Consider a case like: auto x = [] { // something with a runtime diagnostic }; Here, we'll have a DeclForInitializer set, so we'll suppress warnings on the body of the lambda, but we shouldn't: the body of the lambda is a completely different evaluation context from the initialization of the variable x. Can you store the declaration on the ExpressionEvaluationContextRecord instead of storing a list of them directly on Sema? (You shouldn't need a list there, just a single pointer should work, since we can't parse two nested initializers without an intervening evaluation context.) |
clang/lib/Sema/AnalysisBasedWarnings.cpp | ||
2067 | Please capitalize the names of variables. | |
clang/lib/Sema/SemaExpr.cpp | ||
16680–16700 | Please get rid of the pre-existing hacky use of ManglingContextDecl here and move this into the getDeclForInitializer block below. |
clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp | ||
---|---|---|
360 ↗ | (On Diff #215699) | These new warnings seem valid. |
clang/include/clang/Parse/Parser.h | ||
---|---|---|
1873 ↗ | (On Diff #215699) | This should be done by calling a function on Sema (add an ActOnStartDeclInitializer or similar), not by directly modifying Sema's internal state. |
1880 ↗ | (On Diff #215699) | Please add an assertion when you first set this that the old value was null. |
clang/lib/Sema/AnalysisBasedWarnings.cpp | ||
2285 | Consider grabbing VarDeclPossiblyUnreachableDiags[VD] first and avoiding constructing the AnalysisDeclContext at all in the (presumably overwhelmingly common case) that there are no such diagnostics. | |
clang/lib/Sema/SemaDecl.cpp | ||
11853 | We should (presumably) only do this for file-scope variables. The initializers for block-scope variables will be checked when checking the enclosing function (if the variables' declarations are reachable at all). | |
clang/lib/Sema/SemaExpr.cpp | ||
4884 | We should only do this once, when we instantiate the default argument, rather than once each time we use it. (Move this up to just before line 4856?) | |
16665–16666 | This call to getCurFunctionOrMethodDecl() is wrong; it will skip over lambda-expressions. (This is why you're still seeing diagnostics in file-scope lambdas.) Something like this should work: if (Stmts.empty()) { Diag(Loc, PD); return true; } if (FunctionScopeInfo *FSI = getCurFunction()) { FunctionScopes.back()->PossiblyUnreachableDiags.push_back( PossiblyUnreachableDiag(PD, Loc, Stmts)); return true; } // [handle VarDecl case] | |
16682–16684 | No braces here please. Also, this appears to be wrong: we want the declaration with the initializer (which is always VD), not the definition (which might be a different declaration for a static data member), don't we? | |
16695–16700 | What does this fixme mean? | |
clang/test/SemaTemplate/instantiate-static-var.cpp | ||
9 ↗ | (On Diff #215699) | We should not warn here (because this initializer is required to be a constant expression). |
Methods should be UpperCamelCased.