diff --git a/_cmptest/printfdemo/demo.go b/_cmptest/printfdemo/demo.go new file mode 100644 index 00000000..7a20726f --- /dev/null +++ b/_cmptest/printfdemo/demo.go @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package main + +import ( + "fmt" + + "github.com/goplus/llgo/xtool/nm" +) + +func main() { + sym := nm.Symbol{Name: "abc", Type: nm.Text} + fmt.Printf("%016x %c %s\n", sym.Addr, sym.Type, sym.Name) +} diff --git a/internal/lib/reflect/value.go b/internal/lib/reflect/value.go index c2155266..f2d8756f 100644 --- a/internal/lib/reflect/value.go +++ b/internal/lib/reflect/value.go @@ -1579,26 +1579,39 @@ func (v Value) CanUint() bool { // Uint returns v's underlying value, as a uint64. // It panics if v's Kind is not Uint, Uintptr, Uint8, Uint16, Uint32, or Uint64. func (v Value) Uint() uint64 { + f := v.flag k := v.kind() p := v.ptr - switch k { - case Uint: - return uint64(*(*uint)(p)) - case Uint8: - return uint64(*(*uint8)(p)) - case Uint16: - return uint64(*(*uint16)(p)) - case Uint32: - return uint64(*(*uint32)(p)) - case Uint64: - return *(*uint64)(p) - case Uintptr: - return uint64(*(*uintptr)(p)) + if f&flagAddr != 0 { + switch k { + case Uint: + return uint64(*(*uint)(p)) + case Uint8: + return uint64(*(*uint8)(p)) + case Uint16: + return uint64(*(*uint16)(p)) + case Uint32: + return uint64(*(*uint32)(p)) + case Uint64: + return *(*uint64)(p) + case Uintptr: + return uint64(*(*uintptr)(p)) + } + } else if unsafe.Sizeof(uintptr(0)) == 8 { + if k >= Uint && k <= Uintptr { + return uint64(uintptr(p)) + } + } else { + if k >= Uint && k <= Uint32 { + return uint64(uintptr(p)) + } + if k == Uint64 || k == Uintptr { + return *(*uint64)(p) + } } panic(&ValueError{"reflect.Value.Uint", v.kind()}) } -//go:nocheckptr // This prevents inlining Value.UnsafeAddr when -d=checkptr is enabled, // which ensures cmd/compile can recognize unsafe.Pointer(v.UnsafeAddr()) // and make an exception.