Currently clang doesn't verify if the first argument in _builtin_assume_aligned_ is of pointer type. This leads to an assertion build failure. This patch aims to add a check if the first argument is of pointer type or not and diagnose it with diag::err_typecheck_convert_incompatible if its not of pointer type.
Details
Diff Detail
Event Timeline
Thank you for the fix, you need to add a test that exercises the diagnostic you added, I think clang/test/Sema/builtin-assume-aligned.c would be the right place to add it.
Also please add a release note in clang/docs/ReleaseNotes.rst
Removed __builtin_assume_aligned from ignoredbuiltinstest() in clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-vararg.cpp.
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-vararg.cpp | ||
---|---|---|
55 ↗ | (On Diff #518274) | The test should not be removed, it is here for a reason. |
clang/lib/Sema/SemaChecking.cpp | ||
7984 | Variables should have CamelCase names. | |
7986 | Instead of directly checking for the pointer type, it is better to call checkBuiltinArgument, which will handle many corner cases. | |
clang/test/Sema/builtin-assume-aligned.c | ||
75 ↗ | (On Diff #518274) | The expected type is not int *, it is cost void * (according to the definition of the builtin in Builtins.def). |
77 ↗ | (On Diff #518274) | Please add a test that passes an array to the builtin. It should pass. |
clang/lib/Sema/SemaChecking.cpp | ||
---|---|---|
7986 | It looks like this whole block can be replaced by a single function call. |
clang/lib/Sema/SemaChecking.cpp | ||
---|---|---|
7982 | This check is likely also done by checkBuiltinArgument. | |
7989 | checkBuiltinArgument already issues an error if the argument does not have the correct type. |
I have made the requested changes. Please do let me know if any other changes are required
Generally looks good to me, but there were a few minor things. Do you need someone to commit on your behalf once those are addressed? If so, what name and email address would you like used for patch attribution?
clang/docs/ReleaseNotes.rst | ||
---|---|---|
343 ↗ | (On Diff #518425) | |
clang/lib/Sema/SemaChecking.cpp | ||
7982–7991 | The comment doesn't really add too much value, so removing it. | |
clang/test/Sema/builtin-assume-aligned.c | ||
79 ↗ | (On Diff #518348) | +1, test to make sure function to pointer decay happens. |
75 ↗ | (On Diff #518274) | The GCC documentation for this builtin says const void *, Clang has no documentation for this one specifically. |
clang/lib/Sema/SemaChecking.cpp | ||
---|---|---|
7992 | This looks suspicious to me, but I'm no clang expert. |
There's some corresponding code in lib/CodeGen that can be deleted too:
case Builtin::BI__builtin_assume_aligned: { const Expr *Ptr = E->getArg(0); Value *PtrValue = EmitScalarExpr(Ptr); - if (PtrValue->getType() != VoidPtrTy) - PtrValue = EmitCastToVoidPtr(PtrValue); Value *OffsetValue = (E->getNumArgs() > 2) ? EmitScalarExpr(E->getArg(2)) : nullptr;
clang/lib/Sema/SemaChecking.cpp | ||
---|---|---|
7979–7993 | This still seems to be more complex than necessary. If we can't just do this, we should have a comment explaining why. (Eg, does CodeGen really want the final conversion from T* to const void* to not be in the AST?) |
clang/lib/Sema/SemaChecking.cpp | ||
---|---|---|
7979–7993 | As far as I know, alignment sanitizer need a user written type descriptor (but not const void *) to emit diagnostic message, Eg: /app/example.cpp:7:35: runtime error: assumption of 8 byte alignment for pointer of type 'B *' failed So, not only convert T * to const void *, but also we need keep the user written type info. Previously, the solution to this problem was to use below code in codegen: if (auto *CE = dyn_cast<CastExpr>(E)) E = CE->getSubExprAsWritten(); since D133202 and D133583, we only do de default array/function conversion in sema, and convert the 1st arg to const void * in codegen. And I think the current solution is not very good, do you have any other better solutions? Should we keep the original type info in somewhere? Then we can simplify our work in sema. WDYT? |
clang/lib/Sema/SemaChecking.cpp | ||
---|---|---|
7979–7993 | I'm not qualified enough in this area to suggest anything, but I'd assume that the type should live through to CodeGen, where implicit casts should be ignored, if this is necessary.
I'm not sure what's value of mentioning the type here. It already gives the precise location, but whatever. If this needs to be addressed, this should be done in a different patch. |
This patch was submitted by a beginner, because https://github.com/llvm/llvm-project/issues/62305 has the "good first issue" label. From the last few comments, I'm not sure they know how to proceed. Could you summarize what the next steps are?
Thank you for pointing this out! FWIW, I think this is good incremental progress because it fixes a crash. We can leave the AST fidelity work to a follow up. However, I think the comment from @rsmith (https://reviews.llvm.org/D149514#4310865) can be addressed as part of this patch.
clang/lib/Sema/SemaChecking.cpp | ||
---|---|---|
7979–7993 | I think we'd want the AST to have full fidelity, and so that would retain the type through to CodeGen and then ignore the implicit cast from there. However, because this is fixing a crash, I think it's fine to leave that work to follow-up efforts if someone wants to tackle that. |
I have made the requested changes. Please do let me know if other changes are required. Also I would like to thank everyone for their help and guidance.
LGTM, thank you! Do you need someone to commit on your behalf? If so, what name and email address would you like used for patch attribution?
This check is likely also done by checkBuiltinArgument.