This is an archive of the discontinued LLVM Phabricator instance.

[clang][dataflow] Don't analyze templated declarations.
ClosedPublic

Authored by mboehme on May 11 2023, 3:27 AM.

Details

Summary

Attempting to analyze templated code doesn't have a good cost-benefit ratio. We
have so far done a best-effort attempt at this, but maintaining this support has
an ongoing high maintenance cost because the AST for templates can violate a lot
of the invariants that otherwise hold for the AST of concrete code. As just one
example, in concrete code the operand of a UnaryOperator '*' is always a prvalue
(https://godbolt.org/z/s3e5xxMd1), but in templates this isn't true
(https://godbolt.org/z/6W9xxGvoM).

Further rationale for not analyzing templates:

  • The semantics of a template itself are weakly defined; semantics can depend strongly on the concrete template arguments. Analyzing the template itself (as opposed to an instantiation) therefore has limited value.
  • Analyzing templates requires a lot of special-case code that isn't necessary for concrete code because dependent types are hard to deal with and the AST violates invariants that otherwise hold for concrete code (see above).
  • There's precedent in that neither Clang Static Analyzer nor the flow-sensitive warnings in Clang (such as uninitialized variables) support analyzing templates.

Diff Detail

Event Timeline

mboehme created this revision.May 11 2023, 3:27 AM
Herald added a project: Restricted Project. · View Herald Transcript
mboehme requested review of this revision.May 11 2023, 3:27 AM
Herald added a project: Restricted Project. · View Herald TranscriptMay 11 2023, 3:27 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
xazax.hun accepted this revision.May 11 2023, 7:38 AM
This revision is now accepted and ready to land.May 11 2023, 7:38 AM
gribozavr2 accepted this revision.May 11 2023, 12:54 PM
gribozavr2 added inline comments.
clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h
36

Maybe this is too much for a drive-by fix, but since you are changing this API anyway, I have to ask - now that D is nonnull, isn't S strictly redundant? Isn't D always a FunctionDecl, and S its body?

gribozavr2 added inline comments.May 11 2023, 5:40 PM
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
2537

This DerefDependentPtr test was originally added in https://reviews.llvm.org/D117567 and re-landed in https://github.com/llvm/llvm-project/commit/acd4b0359097dd8ad166d569a4566879e82a2793

Could you try to revert the effects of those commits? Specifically:

  • remove reference skipping from the transfer function for UO_Deref (and the comment),
  • remove the -fno-delayed-template-parsing flag from clang/unittests/Analysis/FlowSensitive/TransferTest.cpp.
mboehme updated this revision to Diff 521603.May 12 2023, 4:40 AM

Changes in response to review comments

mboehme marked an inline comment as done.May 12 2023, 4:43 AM
mboehme added inline comments.
clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h
36

Isn't D always a FunctionDecl, and S its body?

This is true for all of the callsites that I've seen, but I think I remember talking to someone who said the intent was that you might also use this to analyze the initializer of a global variable (where D would be the variable declaration and S would be the initializer). It seems telling, at least, that the interface expects only a Decl, not a FunctionDecl.

So I'm hesitant to remove this API entirely without more investigation. It certainly makes sense though to add an overload that takes a FunctionDecl and no Stmt, which will cover the vast majority of use cases. I'd like to do that in a separate patch though.

clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
2537

Thanks for pointing this out! Done.

mboehme updated this revision to Diff 522036.May 14 2023, 9:31 PM
mboehme marked an inline comment as done.

Eliminate warning for use of deprecated function

mboehme updated this revision to Diff 522040.May 14 2023, 9:53 PM

Eliminate warnings for calling deprecated functions

gribozavr2 accepted this revision.May 15 2023, 12:40 AM
mboehme updated this revision to Diff 522075.May 15 2023, 12:46 AM

Set -fnodelayed-template-parsing again.

This is needed to make tests pass on Windows.

mboehme added inline comments.May 15 2023, 12:50 AM
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
2537
  • remove the -fno-delayed-template-parsing flag from clang/unittests/Analysis/FlowSensitive/TransferTest.cpp.

I've re-added this because removing it causes tests to fail on Windows.

-fnodelayed-template-parsing is the default everywhere except on Windows, so setting it explicitly makes tests on Windows behave the same as on other platforms. I've added a comment explaining this.

The reason that -fnodelayed-template-parsing was causing the tests to fail is that checkDataflow() only looks as function declarations that have a body, and late-parsed templated functions don't have bodies.

gribozavr2 accepted this revision.May 15 2023, 12:52 AM
mboehme updated this revision to Diff 522096.May 15 2023, 2:24 AM

Spell -fno-delayed-template-parsing correctly (it was missing a hyphen).

This revision was automatically updated to reflect the committed changes.

Hello,

../../clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp:43:27: error: 'build' is deprecated: Use the version that takes a const Decl & instead [-Werror,-Wdeprecated-declarations]
      ControlFlowContext::build(&FuncDecl, *FuncDecl.getBody(), ASTCtx);
                          ^
../../clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h:41:3: note: 'build' has been explicitly marked deprecated here
  LLVM_DEPRECATED("Use the version that takes a const Decl & instead", "")
  ^
../include/llvm/Support/Compiler.h:143:50: note: expanded from macro 'LLVM_DEPRECATED'
#define LLVM_DEPRECATED(MSG, FIX) __attribute__((deprecated(MSG, FIX)))
                                                 ^
1 error generated.
mboehme added a subscriber: amyk.May 15 2023, 11:56 AM

Hello,

../../clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp:43:27: error: 'build' is deprecated: Use the version that takes a const Decl & instead [-Werror,-Wdeprecated-declarations]
      ControlFlowContext::build(&FuncDecl, *FuncDecl.getBody(), ASTCtx);
                          ^
../../clang/include/clang/Analysis/FlowSensitive/ControlFlowContext.h:41:3: note: 'build' has been explicitly marked deprecated here
  LLVM_DEPRECATED("Use the version that takes a const Decl & instead", "")
  ^
../include/llvm/Support/Compiler.h:143:50: note: expanded from macro 'LLVM_DEPRECATED'
#define LLVM_DEPRECATED(MSG, FIX) __attribute__((deprecated(MSG, FIX)))
                                                 ^
1 error generated.

Sorry for the breakage. I ran check-clang and fixed all the deprecation warnings, so I'm not sure how I missed this one.

Thank you to @amyk for the fix.