Last time, I talked about the $OBJTYPENAME directive. This post has a little something to do with it.

There are issues with using TDateTime, TDate and TTime when you have overloaded routines with differentiating parameters of TDateTime, TDate and TTime.
These issues affect all projects using packages and libraries (to avoid repeating, I'll just use package(s) forthwith).

When projects uses any of the above types and use run-time packages, results might be unexpected on non-mobile platforms, because of the fact that TDate and TTime are exported as aliases of TDateTime, even though they're declared as distinct types, aka typed types.

In 1996-1997, when C++Builder was designed, the Delphi compiler team who designed the Delphi / C++Builder interoperability ran into a problem trying to recreate C++ classes for TDateTIme, TDate and TTime that emulate the semantics of these types in Delphi.

So they took a shortcut and made all three the same type. In other words, TDate and TTime became just aliases of TDateTime (even though they're distinct types!)

How does this impact you? Let's say you declared 3 overloaded routines in the interface section of TDateTimeMangling.Main of the package TDateTimeMangling:

procedure MyProc(Param: TDateTime); overload;
procedure MyProc(Param: TTime); overload;
procedure MyProc(Param: TDate); overload;

The package will then export these routines:

EXPORT ord:0006='@Tdatetimemangling@Main@MyProc$qqr16System@TDateTime'
EXPORT ord:0007='@Tdatetimemangling@Main@MyProc$qqr16System@TDateTime'
EXPORT ord:0005='@Tdatetimemangling@Main@MyProc$qqr16System@TDateTime'

You'll note that the TDateTime, TTime and TDate parameters were all mangled to the same parameter type name: 'qqr16System@TDateTime'

What this means is that if your project uses packages, any time you call MyProc, the call might be dispatched to any one of the three routines, instead of the actual one that you meant.

And the issue remain there, until POSIX platforms got added. Then, fast-forward to when Delphi added support for POSIX platforms where it uses an external linker. The linker do not like that exported overloads with identical mangled names were there, and so, that's why in System.pas, you see that TDate and TTime have their own exported names, while, on platforms that do not use an external linker, TDate and TTime are both named TDateTime when exported in packages.

{$IF defined(EXTERNALLINKER)}
  {$OBJTYPENAME TDate 'NTDate' }
  {$OBJTYPENAME TTime 'NTTime' }
{$ELSE}
  {$OBJTYPENAME TDate 'NTDateTime' }
  {$OBJTYPENAME TTime 'NTDateTime' }
{$ENDIF}

But even if you don't declare overloaded names with TDateTime and family, you're still affected, because TValue in System.Rtti has 3 overloaded Implicit methods using TDateTime and family. And any time you use TDateTime and family with the TValue type, you're affected, because your code could call any one of the three implicit overloads.

This issue also affects overloaded routines with metaclass, and untyped types versus pointers, as metaclass references are type-erased.

If you're affected with these issues, you can choose to use distinct names instead of using overloaded names, in addition to filing a report on Embarcadero's Quality Portal