diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2014-09-29 10:32:21 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2014-09-29 10:32:21 +0000 |
commit | 5bd68794393e51d65ad3c398dfc71ec2bdce7153 (patch) | |
tree | 6c454856cd191b453819af927af699d48f59ada5 /clang/lib | |
parent | 609e2e6a6e001bcbe3da469a0c117fa570ca71aa (diff) | |
download | bcm5719-llvm-5bd68794393e51d65ad3c398dfc71ec2bdce7153.tar.gz bcm5719-llvm-5bd68794393e51d65ad3c398dfc71ec2bdce7153.zip |
Fix bug 20116 - http://llvm.org/bugs/show_bug.cgi?id=20116
Fixes incorrect codegen when devirtualization is aborted due to covariant return types.
Differential Revision: http://reviews.llvm.org/D5321
llvm-svn: 218602
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGExprCXX.cpp | 19 |
1 files changed, 9 insertions, 10 deletions
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp index 7d41af40f6a..483966fce20 100644 --- a/clang/lib/CodeGen/CGExprCXX.cpp +++ b/clang/lib/CodeGen/CGExprCXX.cpp @@ -110,7 +110,15 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE, assert(DevirtualizedMethod); const CXXRecordDecl *DevirtualizedClass = DevirtualizedMethod->getParent(); const Expr *Inner = Base->ignoreParenBaseCasts(); - if (getCXXRecord(Inner) == DevirtualizedClass) + if (DevirtualizedMethod->getReturnType().getCanonicalType() != + MD->getReturnType().getCanonicalType()) + // If the return types are not the same, this might be a case where more + // code needs to run to compensate for it. For example, the derived + // method might return a type that inherits form from the return + // type of MD and has a prefix. + // For now we just avoid devirtualizing these covariant cases. + DevirtualizedMethod = nullptr; + else if (getCXXRecord(Inner) == DevirtualizedClass) // If the class of the Inner expression is where the dynamic method // is defined, build the this pointer from it. Base = Inner; @@ -121,15 +129,6 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE, // we don't have support for that yet, so do a virtual call. DevirtualizedMethod = nullptr; } - // If the return types are not the same, this might be a case where more - // code needs to run to compensate for it. For example, the derived - // method might return a type that inherits form from the return - // type of MD and has a prefix. - // For now we just avoid devirtualizing these covariant cases. - if (DevirtualizedMethod && - DevirtualizedMethod->getReturnType().getCanonicalType() != - MD->getReturnType().getCanonicalType()) - DevirtualizedMethod = nullptr; } llvm::Value *This; |