On Mar 12, 2013, at 10:01 AM, Jordan Rose <[email protected]> wrote:
> Pinging this myself, adding Richard Smith as another reviewer. I don't quite 
> feel qualified to give the final word on it, but I'm fixing an analyzer bug 
> that's basically "don't crash when the user does this in exactly the right 
> wrong way", and it'd be nice to have a warning so that they fix their code.

+def ReinterpretUpDownCastZeroAdjustment :
+  DiagGroup<"reinterpret-updown-zero-adjustment">;
+def ReinterpretUpDownCast : DiagGroup<"reinterpret-updown",

How about -Wreinterpret-base and -Wreinterpret-primary-base?

+def warn_reinterpret_wrong_subobject : Warning<
+  "'reinterpret_cast' might return a pointer to wrong subobject">,

How about "reinterpret_cast %select{from|to}3 class %0 %select{to|from}3 
%select{virtual base|base at non-zero offset}2 %1 behaves differently from 
static_cast"?

+static void DiagnoseReinterpretUpDownCast(Sema &Self, ExprResult &SrcExpr,
+                                          QualType DestType,
+                                          const SourceRange &OpRange) {

You should take SrcExpr as a const Expr * and OpRange as a SourceRange.

+  const Type *SrcUnqualType = SrcType.getTypePtr();
+  const Type *DestUnqualType = DestType.getTypePtr();

This is unnecessary and also doesn't necessarily actually give you an 
unqualified type.

+  // When casting from pointer or reference, get pointee type; use original 
+  // type otherwise.
+  const CXXRecordDecl *SrcPointeeRD = SrcUnqualType->getPointeeCXXRecordDecl();
+  const CXXRecordDecl *SrcRD =
+    SrcPointeeRD ? SrcPointeeRD : SrcUnqualType->getAsCXXRecordDecl();

It'd be good to remember the original non-pointer sugared types here for 
diagnostic purposes.

Also, at this point in semantic analysis you can differentiate between the 
pointer and reference cases by just checking SrcExpr->isRValue().

+  CXXBasePaths SrcBP, DestBP;
+
...
+  const ASTRecordLayout &SrcLayout = Self.Context.getASTRecordLayout(SrcRD);
+  const ASTRecordLayout &DestLayout = Self.Context.getASTRecordLayout(DestRD);

1.  Please sink this down to the point where you need it.
2.  Please only actually get the layout for the derived class.
3.  You can re-use the paths object if the first lookup failed.

+  if (SrcBP.getDetectedVirtual() || DestBP.getDetectedVirtual()) {

You are ignoring the possibility that there are subobjects at multiple paths.  
We should not warn if *any* of the paths is a non-virtually-derived base at 
offset zero.

+  CharUnits Offset = CharUnits::Zero();
+  if (ReinterpretKind == ReinterpretUpcast)
+    Offset = SrcLayout.getBaseClassOffset(DestRD);
+  else if (ReinterpretKind == ReinterpretDowncast)
+    Offset = DestLayout.getBaseClassOffset(SrcRD);

This won't work for indirect base classes.

+  DiagnoseReinterpretUpDownCast(Self, SrcExpr, DestType, OpRange);
+

Please sink this until we've decided that the cast succeeds.

John.


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to