This is an archive of the discontinued LLVM Phabricator instance.

[clang] fixing diagnostics of constexpr callstack
AbandonedPublic

Authored by Tyker on Apr 11 2019, 4:17 AM.

Details

Reviewers
rsmith
Summary

this is a bugfix for this

added a constant copy of argument to CallStackFrame.
and use it in describeCall instead of the modifiable version od arguments.
added test for the diagnostic

Diff Detail

Event Timeline

Tyker created this revision.Apr 11 2019, 4:17 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 11 2019, 4:17 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
Quuxplusone added inline comments.
clang/lib/AST/ExprConstant.cpp
486

Please don't use a typedef for this. Follow the style of the surrounding lines.

const APValue *ConstantArgs;

(The pointer member itself should not be const-qualified. Compare to const LValue *This; two declarations above.)

4520

const APValue *ConstantArgs,

4684

Surely you meant ConstantArgs (plural) here.

clang/test/SemaCXX/constant-expression-cxx1y.cpp
1183

Personally, I would prefer to see something as simple as my original example; I don't think the extra 6 levels of recursion here makes the test any easier to understand.

constexpr int f(int i) {
    i = -i;
    return 1 << i;  // expected-note{{negative shift count -1}}
}
static_assert(f(1));
// expected-error@-1{{static_assert expression is not an integral constant expression}}
// expected-note@-2{{in call to 'f(1)'}}

Also, procedural note: I expect you'll be asked to reupload this diff with full context (git diff -U999 ...).

Tyker updated this revision to Diff 194684.Apr 11 2019, 7:47 AM

@Quuxplusone edited based of feedback

i simplified the test but didn't put the original because this one test arguments for variable and literal and there may be corner case differences

Tyker marked 4 inline comments as done.Apr 11 2019, 7:48 AM

This seems liable to be moderately expensive, especially for large argument values, and it's a cost that is unnecessary in the common case where evaluation succeeds.

I wonder if we'd be better off speculatively trying the entire evaluation without storing any such values, and rerunning the evaluation to collect diagnostics only when we find that evaluation would fail (and we're in a context where the caller actually wants the diagnostics).

Tyker added a comment.EditedApr 12 2019, 11:33 AM

@rsmith i don't think collecting theses values is expansive compared to evaluating the expression.
but i agree that we can disable the collection of these values when no diagnostics can be emited.

@rsmith i don't think collecting theses values is expansive compared to evaluating the expression.
but i agree that we can disable the collection of these values when no diagnostics can be emited.

To help make an informed decision you can grab a big TU (I usually use SemaDecl.cpp or all of Boost) and then run -fsyntax-only on it. With a tool like perf stat you can get pretty good results.

Tyker added a comment.EditedApr 13 2019, 2:16 AM

the impact was much higher than i expected, around 1% slower in average on 50 compilation of SemaDecl with -fsyntax-only.

the impact was much higher than i expected, around 1% slower in average on 50 compilation of SemaDecl with -fsyntax-only.

Good to know, thanks for doing the measurement !

Tyker updated this revision to Diff 195055.Apr 14 2019, 5:14 AM

i changed the way arguments are stored. to make it more controllable.
added an argument call stack where it is needed.
this version slows down compilation by around 0.5% in average over 200 run for SemaDecl -fsyntax-only

Tyker updated this revision to Diff 195056.Apr 14 2019, 5:17 AM
Tyker abandoned this revision.Aug 21 2022, 10:35 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 21 2022, 10:35 AM