This is an archive of the discontinued LLVM Phabricator instance.

[Sema] Fix null pointer dereference handleAlwaysInlineAttr.
ClosedPublic

Authored by craig.topper on Mar 14 2023, 1:34 PM.

Details

Summary

It's possible for getCalleeDecl() to return a null pointer.

This was encountered by a user of our downstream compiler.

The case involved a DependentScopeDeclRefExpr.

Since this seems to only be for a warning diagnostic, I skipped
the diagnostic check if it returned null. But mabye there's a
different way to fix this.

Diff Detail

Event Timeline

craig.topper created this revision.Mar 14 2023, 1:34 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 14 2023, 1:34 PM
craig.topper requested review of this revision.Mar 14 2023, 1:34 PM
Herald added a project: Restricted Project. · View Herald TranscriptMar 14 2023, 1:34 PM

Add a test case

erichkeane added inline comments.Mar 15 2023, 5:59 AM
clang/test/Sema/attr-alwaysinline.cpp
36

Can you add a test that shows that we warn on instantiation? This shouldn't be a dependent declrefexpr when instantiated.

Additionally, this would make sure that we're properly propoagating always_inline.

craig.topper added inline comments.Mar 15 2023, 10:59 AM
clang/test/Sema/attr-alwaysinline.cpp
36

Should this warn

template<int D> [[gnu::noinline]]                                                
int bar(int x) {                                                                 
    if constexpr (D > 1)                                                         
        [[clang::always_inline]] return bar<D-1>(x + 1);                         
    else                                                                         
        return x;                                                                
}                                                                                
                                                                                 
int baz(int x) {                                                                 
  return bar<5>(x);                                                              
}
erichkeane added inline comments.Mar 15 2023, 11:01 AM
clang/test/Sema/attr-alwaysinline.cpp
36

Yes, I would expect that to warn.

craig.topper added inline comments.Mar 15 2023, 12:07 PM
clang/test/Sema/attr-alwaysinline.cpp
36

It looks like handleAlwaysInlineAttr only gets called once so it doesn't get called after instantiation.

erichkeane added inline comments.Mar 15 2023, 12:21 PM
clang/lib/Sema/SemaStmtAttr.cpp
236–237

Same fix + a test probably needed here too.

clang/test/Sema/attr-alwaysinline.cpp
32

Also, I note the 'if constexpr' branch is unnecessary to reproduce this.

36

Hmm... thats unfortunate. That means we're perhaps not instantiating it correctly. I'll take some time to poke around as I get a chacne.

craig.topper added inline comments.Mar 15 2023, 12:34 PM
clang/test/Sema/attr-alwaysinline.cpp
32

Yes, but I didn't bother to figure out what happened if the template recursivley instantiated without bound.

erichkeane added inline comments.Mar 15 2023, 12:37 PM
clang/test/Sema/attr-alwaysinline.cpp
36

Ok, it looks like SemaStmt.cpp's BuildAttributedStmt needs to handle the attributes. We should some day do that automatically for a majority o f attributes, but for now, just adding the call there is sufficient.

craig.topper added inline comments.Mar 15 2023, 12:45 PM
clang/test/Sema/attr-alwaysinline.cpp
36

What I do need to add?

Fix the same bug for noinline attribute

erichkeane added inline comments.Mar 15 2023, 6:16 PM
clang/test/Sema/attr-alwaysinline.cpp
36

You should be able to follow what is already there, but I suspect you just need to call some sort of 'handle' function for those to do this. There is one there already youc an crib off of.

craig.topper added inline comments.Mar 15 2023, 7:15 PM
clang/test/Sema/attr-alwaysinline.cpp
36

Can I do that as a separate patch? Fixing the crash seems like a net improvement.

erichkeane added inline comments.Mar 16 2023, 5:49 AM
clang/test/Sema/attr-alwaysinline.cpp
36

I'd prefer they be done together: They are a situation where you cannot properly test either patch without the other one being fixed, so I believe they are intrinsically linked.

craig.topper added inline comments.Mar 16 2023, 8:44 AM
clang/test/Sema/attr-alwaysinline.cpp
36

I thought not crashing on code that doesn't need to warn would still be an improvement.

The warning that's being lost doesn't seem all that serious. It's just telling that an alwaysinline statement attribute has priority over a noinline function attribute.

We don't warn for this

void foo();

void bar() {
  [[clang::always_inline]] foo();
}

If foo's definition is in another translation unit, the always_inline can't happen without LTO. So foo is effectively noinline without LTO.

erichkeane accepted this revision.Mar 16 2023, 10:13 AM

Please add the test cases requested, plus a Release Note. Otherwise LGTM.

clang/test/Sema/attr-alwaysinline.cpp
36

The warning that's being lost doesn't seem all that serious. It's just telling that an alwaysinline statement attribute has priority over a noinline function attribute.

Isn't it saying that the statement diagnostic is losing to the function attribute?

As far as that example, I wouldn't expect the diagnostic to show there, as you mentioned.

That said, I thought this was going to be a bit more trivial than it is, I thought this was going to be a mild drive-by. There needs to be some level of extracting the getCallExprs checks in both cases into Sema, and have that called upon instantiation.

I think we're OK now with this, but PLEASE make sure to put a number of tests in for the template cases with a "FIXME".

This revision is now accepted and ready to land.Mar 16 2023, 10:13 AM

Please add a release note as requested.

Please add a release note as requested.

To highlight the fix or highlight the missing warning? Or both?

To highlight the fix. See the rest of our release notes.

To highlight the fix. See the rest of our release notes.

4743c03ca8fcb61b8fa4022c38cf93cf55d7f6fd