1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 10:42:39 +01:00
llvm-mirror/include/llvm/IR/GlobalIndirectSymbol.h
Moritz Sichert 2f6870edd6 [IR] Added operator delete to subclasses of User to avoid UB
Several subclasses of User override operator new without also overriding
operator delete. This means that delete expressions fall back to using
operator delete of the base class, which would be User. However, this is
only allowed if the base class has a virtual destructor which is not the
case for User, so this is UB.

See also [expr.delete] (3) for the exact wording.

This is actually detected in some cases by GCC 11's
-Wmismatched-new-delete now which is how I found this error.

Differential Revision: https://reviews.llvm.org/D103143
2021-07-08 11:59:22 +02:00

94 lines
3.2 KiB
C++

//===- llvm/GlobalIndirectSymbol.h - GlobalIndirectSymbol class -*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains the declaration of the GlobalIndirectSymbol class, which
// is a base class for GlobalAlias and GlobalIFunc. It contains all common code
// for aliases and ifuncs.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_IR_GLOBALINDIRECTSYMBOL_H
#define LLVM_IR_GLOBALINDIRECTSYMBOL_H
#include "llvm/IR/GlobalObject.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/OperandTraits.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Casting.h"
#include <cstddef>
namespace llvm {
class GlobalIndirectSymbol : public GlobalValue {
protected:
GlobalIndirectSymbol(Type *Ty, ValueTy VTy, unsigned AddressSpace,
LinkageTypes Linkage, const Twine &Name, Constant *Symbol);
public:
GlobalIndirectSymbol(const GlobalIndirectSymbol &) = delete;
GlobalIndirectSymbol &operator=(const GlobalIndirectSymbol &) = delete;
// allocate space for exactly one operand
void *operator new(size_t S) { return User::operator new(S, 1); }
void operator delete(void *Ptr) { User::operator delete(Ptr); }
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
void copyAttributesFrom(const GlobalValue *Src) {
GlobalValue::copyAttributesFrom(Src);
}
/// These methods set and retrieve indirect symbol.
void setIndirectSymbol(Constant *Symbol) {
setOperand(0, Symbol);
}
const Constant *getIndirectSymbol() const {
return getOperand(0);
}
Constant *getIndirectSymbol() {
return const_cast<Constant *>(
static_cast<const GlobalIndirectSymbol *>(this)->getIndirectSymbol());
}
const GlobalObject *getBaseObject() const;
GlobalObject *getBaseObject() {
return const_cast<GlobalObject *>(
static_cast<const GlobalIndirectSymbol *>(this)->getBaseObject());
}
const GlobalObject *getBaseObject(const DataLayout &DL, APInt &Offset) const {
return dyn_cast<GlobalObject>(
getIndirectSymbol()->stripAndAccumulateInBoundsConstantOffsets(DL,
Offset));
}
GlobalObject *getBaseObject(const DataLayout &DL, APInt &Offset) {
return const_cast<GlobalObject *>(
static_cast<const GlobalIndirectSymbol *>(this)
->getBaseObject(DL, Offset));
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
static bool classof(const Value *V) {
return V->getValueID() == Value::GlobalAliasVal ||
V->getValueID() == Value::GlobalIFuncVal;
}
};
template <>
struct OperandTraits<GlobalIndirectSymbol> :
public FixedNumOperandTraits<GlobalIndirectSymbol, 1> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalIndirectSymbol, Constant)
} // end namespace llvm
#endif // LLVM_IR_GLOBALINDIRECTSYMBOL_H