Skip to content

Conversation

@ojhunt
Copy link
Contributor

@ojhunt ojhunt commented Dec 20, 2025

Adds support for null terminated strings produced by constexpr evaluation. This makes it possible to perform analysis of format strings that previously were not possible, and is needed in the future to support __ptrauth qualifier options.

@ojhunt ojhunt force-pushed the users/ojhunt/consteval-null-terminated-string-constants branch from 0c70ec6 to b769a72 Compare December 20, 2025 08:03
Adds support for null terminated strings produced by constexpr
evaluation. This makes it possible to perform analysis of format
strings that previously were not possible, and is needed in the
future to support __ptrauth qualifier options.
@ojhunt ojhunt force-pushed the users/ojhunt/consteval-null-terminated-string-constants branch from b769a72 to 2a7c39e Compare December 20, 2025 08:04
Comment on lines -297 to +302
if (Ptr.isDummy() || Ptr.isUnknownSizeArray())
if (Ptr.isDummy() || Ptr.isUnknownSizeArray() || Ptr.isPastEnd())
return false;

unsigned N = Ptr.getNumElems();
if (Ptr.elemSize() == 1) {
Result = strnlen(reinterpret_cast<const char *>(Ptr.getRawAddress()), N);
return Result != N;
unsigned Size = N - Ptr.getIndex();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is not possible to hit this in the new interpreter prior to this change, the existing code fails to handle out of bounds pointer into a string literal (or presumably any array), or an in bounds offset.

It feels like it should be in a different PR, but because it can't currently be hit it can't be tested?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@tbaederr maybe has ideas on testing it on it's own?

Copy link
Contributor

Choose a reason for hiding this comment

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

Adding it to this PR is fine IMO.

Copy link
Contributor

Choose a reason for hiding this comment

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

Actually, this might fix #173175, which got filed just 10 minutes ago.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@tbaederr ah ha - I was trying to find a string function that would actually pass that expression to this code but I couldn't work out the correct way to make the call, I think I was trying to get the crash via the first expression, but huzzah we have a test case - will pull this bit out in a moment

Comment on lines +17767 to +17770
if (T->isPointerType() && T->getPointeeType()->isCharType())
return EvaluateAsNullTerminatedCharBuffer(
SemaRef, Message, Result, Ctx, EvalContext, ErrorOnInvalidMessage);

Copy link
Contributor

Choose a reason for hiding this comment

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

The problem of doing that here is that it is a non-standard behavior.
So at the minimum we'd need extension warnings. But I'm a bit uncomfortable adding that extension to begin with.

I think the functionality is best left to format string / ptrauth for now.

Which brings the question... how do we test this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A gross option would be to have a langopt + "enable this" cli flag, but that would imply people be able to rely on being able to do this.

Comment on lines +17730 to +17731
SemaRef.Diag(Loc, diag::ext_consteval_string_constants);
return true;
Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, you put that here! I would put it in the caller

Copy link
Contributor Author

Choose a reason for hiding this comment

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

if we make evaluating a null terminated expression a flag or mode then we can remove this condition - maybe I should then just make the format string or similar routines use the "evaluate null terminated expressions" flag? it seems like such a change would be a minor change (he says with unfounded optimism)

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.

4 participants