Emacs has no way of knowing when the shell actually changes its directory. This is an intrinsic limitation of Unix. So it tries to guess by recognizing `cd' commands. If you type `cd' followed by a directory name with a variable reference (`cd $HOME/bin') or with a shell metacharacter (`cd ../lib*'), Emacs will fail to correctly guess the shell's new current directory. A huge variety of fixes and enhancements to Shell mode for this problem have been written to handle this problem. Check the Lisp Code Directory (see section How do I find a GNU Emacs Lisp package that does XXX?).