checkedc / checkedc-llvm-project

This was a fork of Checked C clang used from 2021-2024. The changes have been merged into the original Checked C clang repo, which is now at https://github.com/checkedc/checkedc-clang.
https://www.checkedc.org
13 stars 19 forks source link

Generic Structs for Checked C #633

Open secure-sw-dev-bot opened 2 years ago

secure-sw-dev-bot commented 2 years ago

This issue was copied from https://github.com/microsoft/checkedc-clang/issues/637


This is a tracking issue for adding generic structs to Checked C.

secure-sw-dev-bot commented 2 years ago

Comment from @abeln:

MERGED

secure-sw-dev-bot commented 2 years ago

Comment from @abeln:

MERGED

Support for itypes.

secure-sw-dev-bot commented 2 years ago

Comment from @abeln:

After the itypes PR above is merged, there's one remaining TODO. See https://github.com/microsoft/checkedc-clang/pull/660#discussion_r317836958

"I think we can follow up on this in separate pull request. Please open an issue and leave some TODO's in the code.

Yes, type variables can appear inside casts too. The correct solution is to rewrite the bounds expression. TreeTransform can do that too. You can use TypeApplication::TransformExpr to transform an expression.

You would need to move the substitution class earlier in the file be able to invoke it. Alternatively, you could create a version of SubstituteTypeArgs that works for expressions.

By the way, I noticed that SubstituteTypeArgs is actually specialized for usage in a polymorphic function type application (it checks whether there the type is a function type). It isn't quite the right thing to use for substitution of types of members.

Another subtlety is that substitution may not result in any change to an expression. So before you take an action to create a new AST node based on a transformed expression, you should check to make sure that it has actually changed."

secure-sw-dev-bot commented 2 years ago

Comment from @abeln:

Here's another TODO for this one that David and I discussed:

Right now the representation of type applications is somewhat hacky. We use RecordDecls to represent both generic struct definitions and their applications.

e.g. struct Foo _For_any(T) is a RecordDecl(isGeneric = true, typeParameters = [T])

and a subsequent application struct Foo<int> is a RecordDecl(isApplication = true, typeArguments=[T])

What we really want here is a dedicated type for type applications, such that struct Foo<int> is its own type node TypeApp(pointer_to_foo_type, [list_of_type_arguments])

Related to this is the idea that we need to properly canonicalize type applications. Right now each type application is its own canonical type, which leads to problems when caching them. What we want is the type application TypeApp(Foo, [Arg]) to be canonicalized to TypeApp(canon(Foo), [canon(Arg)]). canon(Foo) will probably end up as Foo, but canon('Arg') might be != Arg: e.g. canon(TypeApp(Foo, T)) = TypeApp(Foo, int) if T has been typedef'ed to int.

secure-sw-dev-bot commented 2 years ago

Comment from @abeln:

Assigning back to @dtarditi for future work.