Skip to content

[2026-06 CWG Motion 2] P3596R3 Undefined Behavior and IFNDR Annexes#9107

Merged
tkoeppe merged 4 commits into
cplusplus:mainfrom
notadragon:ub-ifndr-cwgreview1
Jul 12, 2026
Merged

[2026-06 CWG Motion 2] P3596R3 Undefined Behavior and IFNDR Annexes#9107
tkoeppe merged 4 commits into
cplusplus:mainfrom
notadragon:ub-ifndr-cwgreview1

Conversation

@notadragon

Copy link
Copy Markdown
Contributor

Fixes #9069
Also fixes cplusplus/papers#2623

This is from the branch from which the paper was generated, with a small number of editorial changes already made:

  1. Most notable, after rendering the standard the annex titles were very large and wrapping to multiple lines. After discussion, Jens and I shortened them by removing "Enumeration of" from each one.
  2. One set of comments was fixed to use "IFNDR" the way the rest of the annex does instead of the (comma-less) "ill formed no diagnostic required"
  3. One bug that was discovered during wording review of another paper was fixed, but that entry will also be removed when that paper lands in a later motion.
  4. The \lastcorechapter macro was used where it was supposed to be used because my paper rendering couldn't handle that when the P paper was generated.

@shafik shafik left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finished UB section.

Comment thread source/ub.tex Outdated
\end{codeblock}
\end{example}

\ubdescription{conv.fpint.float.not.represented}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super minor but I think this one should be swapped w/ conv.fpint.int.not.represented b/c in 7.3.11 we have E.3.8 first and then E.3.7 but again super minor nit.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will rearrange.

Comment thread source/ub.tex Outdated

\pnum
Evaluating a \keyword{dynamic_cast} on a reference that
denotes an object (of polymorphic type) of the wrong type or an object

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
denotes an object (of polymorphic type) of the wrong type or an object
denotes an object (of polymorphic type) of the similar type or an object

I am not sure but looking at the core wording, I think that is more correct?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"of the similar type" is wrong, similar type would be fine. "wrong" type could be interpreted broadly as "any type that is wrong for doing this" but we can be more precise and say "of a type that is not similar" . I will change to that.

Comment thread source/ub.tex Outdated
\pnum
\begin{example}
\begin{codeblock}
struct S {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't indicate the UB in the example and why didn't you use the simpler example from 7.6.6? Maybe this was my original example?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i will compact this example slightly and add a comment about the UB. Not sure who the example dates back to (probably you). I would rather not rewrite examples entirely in this phase so will leave switching to clearer/simpler examples for followup efforts.

Comment thread source/ub.tex Outdated
\ubdescription{expr.assign.overlap}

\pnum
Overlap in the storage between the source and destination may result in undefined behavior.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be using may here?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

may -> can

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

Comment thread source/ub.tex Outdated
\ubdescription{class.base.init.mem.fun}

\pnum
It is undefined behavior to call a member function before all the \grammarterm{mem-initializer}s for base classes have completed.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like there are two contracts cases added that we are missing. This feels minor and we can add afterwards too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am prepping a PR with new/missing entries and any entries that need major updating after all of the Brno motions land, I will make note to include this in that PR (and the paper that will be generated from that PR). I think it should wait until after all of the Brno motions land.

@jensmaurer

Copy link
Copy Markdown
Member

@notadragon, please squash all commits into the first one; we don't need the details of the genesis preserved for posterity.

@jensmaurer

Copy link
Copy Markdown
Member

@notadragon, do we have "ubx" as part of a visible label in the Annex headings now? We shouldn't; those visible labels should be "ub:something". (Similarly with ifndrx, if any).

@shafik shafik left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finished reviewing IFNDR annex. Really minor comments. I think we are in good shape here.

Comment thread source/ifndr.tex
\ifndrdescription{module.unit.named.module.no.partition}

\pnum
Having multiple primary module interface units

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure this description matches what the wording says but I may just not be reading it correctly.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The wording defines "primary module interface unit" and says, effectively, "A named module shall contain one module interface unit that meets that definition, no diagnostic required". As far as I can tell that's what the annex entry is saying as well, though i'm happy to adjust if it's wrong or there's clearer wording. Leaving this as-is for now.

@notadragon

Copy link
Copy Markdown
Contributor Author

@notadragon, do we have "ubx" as part of a visible label in the Annex headings now? We shouldn't; those visible labels should be "ub:something". (Similarly with ifndrx, if any).

No, I swapped which label is "ub:" and which is "ubx:", and I also made the "stable names" shown in the annex start with "ub:" and ifndr:.

Here's some screenshots of my locally built copy of the standard for review:

image image

@notadragon
notadragon force-pushed the ub-ifndr-cwgreview1 branch from c26a110 to 3e05f52 Compare June 22, 2026 16:36
@notadragon

Copy link
Copy Markdown
Contributor Author

@jensmaurer @shafik I've addressed, I believe, all of your comments.

@shafik

shafik commented Jun 22, 2026

Copy link
Copy Markdown

@jensmaurer @shafik I've addressed, I believe, all of your comments.

Thank you so much for all this work to get the annexes landed in the draft! I am happy with direction in your replies.

@tkoeppe
tkoeppe force-pushed the ub-ifndr-cwgreview1 branch 4 times, most recently from 1ef0f08 to 9d9e262 Compare July 11, 2026 23:56
joshuaberne and others added 4 commits July 12, 2026 10:53
Editorial notes:
* minor adjustments to comment placement, capitalisation and
  punctuation
* punctuation fixes
* rephrased some colloquialisms (like "we" and "kick off")
* dropped an unhelpful and imprecise comment Example 2 of
  [ub:expr.add.out.of.bounds]
The original wording was somewhat colloquial and needlessly
inconsistent in places.
Currently, the example contains no explanations of how it demonstrates
the behaviour in question.
@tkoeppe
tkoeppe force-pushed the ub-ifndr-cwgreview1 branch from 40d7454 to f0a1a4e Compare July 12, 2026 09:53
@tkoeppe
tkoeppe merged commit ea6540b into cplusplus:main Jul 12, 2026
2 checks passed
Comment thread source/ifndr.tex
Comment on lines +299 to +300
new int[-(int)sizeof(T)]; // IFNDR, the size of the allocation is required to be greater
// than zero but can never be

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This example seems to be well-formed per the analysis in #6055. Looks like that we incorrectly copied a legacy example.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've landed this motion, but I am going to do a pass at a followup PR to clean up any discovered issues/gaps and to reconcile with the other motions that landed in Brno. I'll try to address this in that PR. (Though recommended alternative examples are welcome.)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can adopt the proposed example in #6062.

  new decltype((void)T{});      // IFNDR, the type of the object to create is never valid

Comment thread source/ifndr.tex
\begin{codeblocktu}{Translation unit \#2}
inline void f() {} // OK, same as \#1
inline void g() {;} // IFNDR, different sequence of tokens than \#2
inline void h() {[]{}();} // IFNDR, closure has different type than \#3

@frederick-vs-ja frederick-vs-ja Jul 15, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Such 2 definitions of h seem to be well-formed per CWG2300. Perhaps we should change to use default arguments.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, this is also not right, i will try to include a fix in the followup PR/paper. (Concrete alternative examples are welcome)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can just change the case to inline void h(void (*)() = []{}()) {}.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can just change the case to inline void h(void (*)() = []{}()) {}.

Note that the example added in CWG2300 is:

inline void g(bool cond, void (*p)() = []{}) {
    if (cond) g(false);
}

I believe it is necessary to include the recursive call, if it was not then it presumably would have been omitted.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had gone with a local function declaration being called, but i think the recursive call is better. I will update it. (See https://isocpp.org/files/papers/D4284R0.pdf for the fixes i intend to land)

Comment thread source/ifndr.tex
Comment on lines +35 to +41
int _z; // IFNDR, \tcode{\_z} is reserved because it starts with \tcode{\_} at global scope

int main() {
int __x; // IFNDR, \tcode{\_\_x} is reserved because it starts with \tcode{\_\_}
int _Y; // IFNDR, \tcode{\_Y} is reserved because it starts with \tcode{\_} followed by a capital letter
int x__y; // IFNDR, \tcode{x\_\_y} is reserved because it contains \tcode{\_\_}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason these underscores have backslashes before them? It seems inconsistent since this is the only place that does it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because underscores in LaTeX are stupid. These render the same way either way _, so removing them would be purely editorial. (I will remove them in the PR for https://isocpp.org/files/papers/D4284R0.pdf).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to cause issues with rendering on https://eel.is/c++draft/ifndr:lex.name.reserved.

@tkoeppe

tkoeppe commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

We have macros to produce double underscores if that's an issue...

@notadragon

Copy link
Copy Markdown
Contributor Author

We have macros to produce double underscores if that's an issue...

The standard renders fine without the _s, we can just remove them. I only put them there out of personal habit. (Though this also sounds like it is triggered by an eel.is problem, not an us problem :) )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[2026-06 CWG Motion 2] P3596R3 Undefined Behavior and IFNDR Annexes P3596 R3 Undefined Behavior and IFNDR Annexes

8 participants