This is an archive of the discontinued LLVM Phabricator instance.

Extend ptr32 support to be applied on typedef
ClosedPublic

Authored by Ariel-Burton on Jul 19 2022, 1:42 PM.

Details

Summary

Earlier, if the QualType was sugared, then we would error out
as it was not a pointer type, for example,

typedef int *int_star;

int_star __ptr32 p;

Now, if ptr32 is given we apply it if the raw Canonical Type
(i.e., the desugared type) is a PointerType, instead of only
checking whether the sugared type is a pointer type.

As before, we still disallow ptr32 usage if the pointer is used
as a pointer to a member.

Diff Detail

Event Timeline

Ariel-Burton created this revision.Jul 19 2022, 1:42 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 19 2022, 1:42 PM
Ariel-Burton requested review of this revision.Jul 19 2022, 1:42 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 19 2022, 1:42 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
akhuang accepted this revision.Jul 19 2022, 1:56 PM

Looks good, thanks!

This revision is now accepted and ready to land.Jul 19 2022, 1:56 PM
Ariel-Burton retitled this revision from [Phabricator] extend ptr32 support to be applied on typedef to Extend ptr32 support to be applied on typedef.Jul 19 2022, 2:04 PM
rnk added inline comments.Jul 19 2022, 3:22 PM
clang/lib/Sema/SemaType.cpp
7163

This seems like a good place to use getSingleStepDesugaredType to look through all type sugar (parens, typedefs, template substitutions, etc).

Ariel-Burton added inline comments.Jul 19 2022, 7:22 PM
clang/lib/Sema/SemaType.cpp
7163

This seems like a good place to use getSingleStepDesugaredType to look through all type sugar (parens, typedefs, template substitutions, etc).

I'm not sure what you mean. Could you expand a little, please?

rnk added inline comments.Jul 20 2022, 10:56 AM
clang/lib/Sema/SemaType.cpp
7163

Clang's AST has lots of "type sugar nodes". These are types which usually don't have any semantic meaning, they just carry source location information, like whether there was a typedef or extra parens in the type. AttributedType is also a type sugar node, so we cannot do a full desugaring here, we have to step through each node one at a time to accumulate the attributes.

Your code looks through one kind of type sugar, but this loop should probably be generalized to handle all kinds of type sugar. I think getSingleStepDesugaredType will do that.

Ariel-Burton added inline comments.Jul 20 2022, 4:49 PM
clang/lib/Sema/SemaType.cpp
7163

Thanks for the clarification. Do you mean something like:

for (;;) {
   const AttributedType *AT = dyn_cast<AttributedType>(Desugared);
   if (AT) {
     Attrs[AT->getAttrKind()] = true;
     Desugared = AT->getModifiedType();
   } else {
     QualType QT = Desugared.getSingleStepDesugaredType(S.Context);
     if (Desugared != QT) {
       Desugared = QT;
     } else {
       break;
     }
   }
 }

I don't think that we can use getSingleStepDesugaredType indiscriminately. Not all sugar should be peeled away, for example, in the case of of parentheses:

int *(__ptr32 wrong);

is accepted when it shouldn't.

To check for the cases where we don't want to desugar has the same sort of complexity as checking for the cases where we do. I suggest going with the original proposal.

rnk added a comment.Aug 1 2022, 8:00 AM

That sounds reasonable to me, I confirmed that MSVC really only lets you apply these attributes directly to pointer types and to typedefs.

Can you add a test for the other most common type sugar node, the template parameter? It looks like this:

template <typename T>
void f(T __ptr32 a) {
    (*a) += 1;
}
void g(int *p) {
    f(p);
}

If there isn't already a C++ test for __ptr32 & co, go ahead and make one.

clang/lib/Sema/SemaType.cpp
7197

I raised the issue because it wasn't clear if we had a definitive answer for the question in this FIXME.

That sounds reasonable to me, I confirmed that MSVC really only lets you apply these attributes directly to pointer types and to typedefs.

Can you add a test for the other most common type sugar node, the template parameter? It looks like this:

template <typename T>
void f(T __ptr32 a) {
    (*a) += 1;
}
void g(int *p) {
    f(p);
}

If there isn't already a C++ test for __ptr32 & co, go ahead and make one.

What is your expectation for your template code fragment? MSVC does not accept it.

On the other hand, MSVC does accept this:

template <typename T>
void f(T  a) {
  (*a) += sizeof(a);
}
void g(int *p) {
  f(p);
}
void h(int *__ptr32 p) {
    f(p);
}
rnk added a comment.Aug 3 2022, 9:31 AM

What is your expectation for your template code fragment? MSVC does not accept it.

Yes, I checked, MSVC rejects it, so clang should have test expectations to confirm that. It seems interesting or surprising, to me at least, that MSVC really only accepts __ptr32 on pointers and typedefs of them.

On the other hand, MSVC does accept this:

template <typename T>
void f(T  a) {
  (*a) += sizeof(a);
}
void g(int *p) {
  f(p);
}
void h(int *__ptr32 p) {
    f(p);
}

Right, this makes sense to me. MSVC's diagnostics say something about the __ptr32 qualifier needing to appear after a *, so this extension must be implemented at a pretty low-level, with some exception for typedefs, just like what you have.

What is your expectation for your template code fragment? MSVC does not accept it.

Yes, I checked, MSVC rejects it, so clang should have test expectations to confirm that. It seems interesting or surprising, to me at least, that MSVC really only accepts __ptr32 on pointers and typedefs of them.

On the other hand, MSVC does accept this:

template <typename T>
void f(T  a) {
  (*a) += sizeof(a);
}
void g(int *p) {
  f(p);
}
void h(int *__ptr32 p) {
    f(p);
}

Right, this makes sense to me. MSVC's diagnostics say something about the __ptr32 qualifier needing to appear after a *, so this extension must be implemented at a pretty low-level, with some exception for typedefs, just like what you have.

Thanks.

Just to make sure that we're on the same page, you'd like to see a test that confirms that clang is rejecting the template<typename T> void f(T __ptr32 a) example, and possibly one that checks that my example is accepted. Is that correct?

rnk added a comment.Aug 4 2022, 10:26 AM

Just to make sure that we're on the same page, you'd like to see a test that confirms that clang is rejecting the template<typename T> void f(T __ptr32 a) example, and possibly one that checks that my example is accepted. Is that correct?

Yep, exactly that. Sorry for the delay, the code looks good.

Added C++ tests for __ptr32.

Recover original changes, and commit with new C++ __ptr32 test.

Just to make sure that we're on the same page, you'd like to see a test that confirms that clang is rejecting the template<typename T> void f(T __ptr32 a) example, and possibly one that checks that my example is accepted. Is that correct?

Yep, exactly that. Sorry for the delay, the code looks good.

Please see updated test clang/test/Sema/MicrosoftExtensions.cpp

rnk accepted this revision.Aug 4 2022, 3:54 PM

lgtm, thanks!

  • Add case to deal with ElaboratedTypes.
rnk accepted this revision.Aug 8 2022, 3:48 PM
  • Add case to deal with ElaboratedTypes.

Let's still stick with this code, but I at least feel justified raising the concern that perhaps we should look through other kinds of type sugar. :)

This revision was automatically updated to reflect the committed changes.