Canonical param types and restrict array index qualifiers

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 17 11:18:06 PDT 2017


On Mon, Apr 17, 2017 at 2:14 PM, Richard Smith <richard at metafoo.co.uk> wrote:
> C11 6.7.6.3p15: "In the determination of type compatibility and of a
> composite type, each parameter declared with function or array type is taken
> as having the adjusted type and each parameter declared with qualified type
> is taken as having the unqualified version of its declared type."
>
> So "int f(int p[restrict])" is compatible with "int f(int *restrict p)" and
> "int f(int *p)", so getCanonicalParamType should be stripping the qualifiers
> (if any) added by getArrayDecayedType -- or not adding them in the first
> place. Seems like the same bug exists for "int f(int p[const])" and "int
> f(int p[volatile])" too.
>
> An even more broken case along the same codepath is the bizarre construct
> "int f(int arr[_Nullable])". The canonical function type should not include
> the nullability attribute (it's not even part of the canonical parameter
> type), but currently it does! Our current handling for this case is clearly
> wrong: getCanonicalParamType returns a CanQualType wrapping an
> AttributedType, which is not a canonical type.
>
> Maybe the easiest fix would be to make getCanonicalParamType just build the
> type "pointer to array element type" and not call getArrayDecayedType at
> all, since it doesn't want any of the other things that getArrayDecayedType
> does.

I'm happy to make that change, however, I'm struggling to devise a
good test case that doesn't rely on my out-of-tree code to demonstrate
the problem. Do you happen to have a reasonable test case for me to
work from?

~Aaron

>
> On 17 April 2017 at 10:07, Aaron Ballman via cfe-commits
> <cfe-commits at lists.llvm.org> wrote:
>>
>> I've run into a case where I am calling ASTContext::getFunctionType()
>> and getting a failed assertion because a parameter we thought we
>> canonicalized isn't actually canonical. The function is declared as:
>>
>> extern int regexec (int __pmatch[__restrict]);
>>
>> When we call getCanonicalParamType() on that parameter, it results in
>> a type that is a decayed pointer that still has the restrict
>> qualifier, because getArrayDecayedType() leaves on index type
>> qualifiers. However, isCanonicalAsParam() checks for the presence of
>> any local qualifiers and returns false if any are present. This
>> results in the assertion failing.
>>
>> I believe this is a bug, but I'm not certain where. Should
>> getCanonicalParamType() be stripping the restrict array index
>> qualifier? Should isCanonicalAsParam() be modified? Or is something
>> else going on that I'm not quite understanding?
>>
>> Thanks!
>>
>> ~Aaron
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
>


More information about the cfe-commits mailing list